{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "uf-ZAG8ddOxf" }, "source": [ "# Forex Arbitrage\n", "\n", "This notebook presents an example of linear optimization on a network model for financial transactions. The goal is to identify whether or not an arbitrage opportunity exists given a matrix of cross-currency exchange rates. Other treatments of this problem and application are available, including the following links.\n", "\n", "* [Crypto Arbitrage Framework](https://github.com/hzjken/crypto-arbitrage-framework)\n", "* [Crypto Trading and Arbitrage Identification Strategies](https://nbviewer.org/github/rcroessmann/sharing_public/blob/master/arbitrage_identification.ipynb)\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 9828, "status": "ok", "timestamp": 1647615556911, "user": { "displayName": "Jeffrey Kantor", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gg_n8V7bVINy02QRuRgOoMo11Ri7NKU3OUKdC1bkQ=s64", "userId": "09038942003589296665" }, "user_tz": 240 }, "id": "RkfYiXhygbos", "outputId": "e418700e-0848-495b-ed17-38e23604ce1e" }, "outputs": [], "source": [ "# install dependencies and select solver\n", "%pip install -q amplpy networkx matplotlib numpy pandas\n", "\n", "SOLVER = \"cbc\"\n", "\n", "from amplpy import AMPL, ampl_notebook\n", "\n", "ampl = ampl_notebook(\n", " modules=[\"cbc\"], # modules to install\n", " license_uuid=\"default\", # license to use\n", ") # instantiate AMPL object and register magics" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import io\n", "import networkx as nx\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": { "id": "uf-ZAG8ddOxf" }, "source": [ "## Problem\n", "\n", "Exchanging one currency for another is among the most common of all banking transactions. Currencies are normally priced relative to each other. \n", "\n", "At this moment of this writing, for example, the Japanese yen (symbol JPY) is priced at 0.00761 relative to the euro (symbol EUR). At this price 100 euros would purchase 100/0.00761 = 13,140.6 yen. Conversely, EUR is priced at 131.585 yen. The 'round-trip' of 100 euros from EUR to JPY and back to EUR results in\n", "\n", "$$100 \\text{ EUR} \\times \\frac{1\\text{ JPY}}{0.00761\\text{ EUR}} {\\quad\\longrightarrow\\quad} 12,140.6 \\text{ JPY} \\times\\frac{1\\text{ EUR}}{131.585\\text{ JPY}} {\\quad\\longrightarrow\\quad} 99.9954\\text{ EUR}$$\n", "\n", "The small loss in this round-trip transaction is the fee collected by the brokers and banking system to provide these services. \n", "\n", "Needless to say, if a simple round-trip transaction like this reliably produced a net gain then there would many eager traders ready to take advantage of the situation. Trading situations offering a net gain with no risk are called arbitrage, and are the subject of intense interest by traders in the foreign exchange (forex) and crypto-currency markets around the globe.\n", "\n", "As one might expect, arbitrage opportunities involving a simple round-trip between a pair of currencies are almost non-existent in real-world markets. When the do appear, they are easily detected and rapid and automated trading quickly exploit the situation. More complex arbitrage opportunities, however, can arise when working with three more currencies and a table of cross-currency exchange rates.\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "J-ADrgCoQP3L" }, "source": [ "## Demonstration of Triangular Arbitrage\n", "\n", "Consider the following cross-currency matrix. \n", "\n", "| i <- J | USD | EUR | JPY |\n", "| :--- | :---: | :---: | :---: |\n", "| USD | 1.0 | 2.0 | 0.01 |\n", "| EUR | 0.5 | 1.0 | 0.0075 |\n", "| JPY | 100.0 | 133 1/3 | 1.0 |\n", "\n", "\n", "Entry $a_{m, n}$ is the number units of currency $m$ received in exchange for one unit of currency $n$. We use the notation \n", "\n", "$$a_{m, n} = a_{m \\leftarrow n}$$\n", "\n", "as reminder of what the entries denote. For this data there are no two way arbitrage opportunities. We can check this by explicitly computing all two-way currency exchanges\n", "\n", "$$I \\rightarrow J \\rightarrow I$$\n", "\n", "by computing\n", "\n", "$$ a_{i \\leftarrow j} \\times a_{j \\leftarrow i}$$\n", "\n", "This data set shows no net cost and no arbitrage for conversion from one currency to another and back again." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 196 }, "executionInfo": { "elapsed": 208, "status": "ok", "timestamp": 1647604331600, "user": { "displayName": "Jeffrey Kantor", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gg_n8V7bVINy02QRuRgOoMo11Ri7NKU3OUKdC1bkQ=s64", "userId": "09038942003589296665" }, "user_tz": 240 }, "id": "TsL1c79nx3aN", "outputId": "59b9aec9-bae7-426a-9556-27fc0787ebdd" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
USDEURJPY
USD1.02.0000000.0100
EUR0.51.0000000.0075
JPY100.0133.3333331.0000
\n", "
" ], "text/plain": [ " USD EUR JPY\n", "USD 1.0 2.000000 0.0100\n", "EUR 0.5 1.000000 0.0075\n", "JPY 100.0 133.333333 1.0000" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "1.0\n", "1.0\n", "1.0\n" ] } ], "source": [ "df = pd.DataFrame(\n", " [[1.0, 0.5, 100], [2.0, 1.0, 1 / 0.0075], [0.01, 0.0075, 1.0]],\n", " columns=[\"USD\", \"EUR\", \"JPY\"],\n", " index=[\"USD\", \"EUR\", \"JPY\"],\n", ").T\n", "\n", "display(df)\n", "\n", "# USD -> EUR -> USD\n", "print(df.loc[\"USD\", \"EUR\"] * df.loc[\"EUR\", \"USD\"])\n", "\n", "# USD -> JPY -> USD\n", "print(df.loc[\"USD\", \"JPY\"] * df.loc[\"JPY\", \"USD\"])\n", "\n", "# EUR -> JPY -> EUR\n", "print(df.loc[\"EUR\", \"JPY\"] * df.loc[\"JPY\", \"EUR\"])" ] }, { "cell_type": "markdown", "metadata": { "id": "wmcvV5oiQ27w" }, "source": [ "Now consider a currency exchange comprised of three trades that returns back to the same currency.\n", "\n", "$$ I \\rightarrow J \\rightarrow K \\rightarrow I $$\n", "\n", "The net exchange rate can be computed as\n", "\n", "$$ a_{i \\leftarrow k} \\times a_{k \\leftarrow j} \\times a_{j \\leftarrow i} $$\n", "\n", "By direct calculation we see there is a three-way **triangular** arbitrage opportunity for this data set that returns a 50% increase in wealth." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 2, "status": "ok", "timestamp": 1647604332177, "user": { "displayName": "Jeffrey Kantor", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gg_n8V7bVINy02QRuRgOoMo11Ri7NKU3OUKdC1bkQ=s64", "userId": "09038942003589296665" }, "user_tz": 240 }, "id": "MvHEDf2zUJqS", "outputId": "d8570d6e-d2b8-41af-dc6e-47c3afce010d" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.5\n" ] } ], "source": [ "I = \"USD\"\n", "J = \"JPY\"\n", "K = \"EUR\"\n", "\n", "print(df.loc[I, K] * df.loc[K, J] * df.loc[J, I])" ] }, { "cell_type": "markdown", "metadata": { "id": "SGv4WjmTx3aO" }, "source": [ "Our challenge is create a model that can identify complex arbitrage opportunities that may exist in cross-currency forex markets." ] }, { "cell_type": "markdown", "metadata": { "id": "Y_tuUX8XqnwA" }, "source": [ "## Modeling\n", "\n", "The cross-currency table $A$ provides exchange rates among currencies. Entry $a_{i,j}$ in row $i$, column $j$ tells us how many units of currency $i$ are received in exchange for one unit of currency $j$. We'll use the notation $a_{i, j} = a_{i\\leftarrow j}$ to remind ourselves of this relationship.\n", "\n", "We start with $w_j(0)$ units of currency $j \\in N$, where $N$ is the set of all currencies in the data set. We consider a sequence of trades $t = 1, 2, \\ldots, T$ where $w_j(t)$ is the amount of currency $j$ on hand after completing trade $t$.\n", "\n", "Each trade is executed in two phases. In the first phase an amount $x_{i\\leftarrow j}(t)$ of currency $j$ is committed for exchange to currency $i$. This allows a trade to include multiple currency transactions. After the commitment the unencumbered balance for currency $j$ must satisfy trading constraints. Each trade consists of simultaneous transactions in one or more currencies.\n", "\n", "$$w_j(t-1) - \\sum_{i\\ne j} x_{i\\leftarrow j}(t) \\geq 0$$\n", "\n", "Here a lower bound has been placed to prohibit short-selling of currency $j$. This constraint could be modified if leveraging is allowed on the exchange.\n", "\n", "The second phase of the trade is complete when the exchange credits all of the currency accounts according to\n", "\n", "$$ w_j(t) = w_j(t-1) - \\underbrace{\\sum_{i\\ne j} x_{i\\leftarrow j}(t)}_{\\text{outgoing}} + \\underbrace{\\sum_{i\\ne j} a_{j\\leftarrow i}x_{j\\leftarrow i}(t)}_{\\text{incoming}} $$\n", "\n", "We assume all trading fees and costs are represented in the bid/ask spreads represented by $a_{j\\leftarrow i}$\n", "\n", "The goal of this calculation is to find a set of transactions $x_{i\\leftarrow j}(t) \\geq 0$ to maximize the value of portfolio after a specified number of trades $T$.\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting arbitrage.mod\n" ] } ], "source": [ "%%writefile arbitrage.mod\n", "\n", "set T0;\n", "set T1;\n", " \n", "# currency *nodes*\n", "set NODES;\n", "\n", "# paths between currency nodes i -> j\n", "set ARCS within {NODES,NODES};\n", "\n", "param T;\n", "param R symbolic;\n", "param a{NODES, NODES};\n", "\n", "# w[i, t] amount of currency i on hand after transaction t\n", "var w{NODES, T0} >= 0;\n", "\n", "# x[m, n, t] amount of currency m converted to currency n in transaction t t\n", "var x{ARCS, T1} >= 0;\n", "\n", "# start with assignment of 100 units of a selected reserve currency\n", "s.t. initial_condition{i in NODES}:\n", " w[i, 0] == (if i == R then 100 else 0);\n", "\n", "# no shorting constraint\n", "s.t. max_trade {j in NODES, t in T1}:\n", " w[j, t-1] >= sum{i in NODES: i != j} x[i, j, t];\n", "\n", "# one round of transactions\n", "s.t. balances {j in NODES, t in T1}:\n", " w[j, t] ==\n", " w[j, t-1] - \n", " sum{i in NODES: i != j} x[i, j, t] + \n", " sum{i in NODES: i != j} a[j, i] * x[j, i, t];\n", "\n", "maximize wealth: w[R, T];" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 133, "status": "ok", "timestamp": 1647604334065, "user": { "displayName": "Jeffrey Kantor", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gg_n8V7bVINy02QRuRgOoMo11Ri7NKU3OUKdC1bkQ=s64", "userId": "09038942003589296665" }, "user_tz": 240 }, "id": "NzTVF6JOW8-S", "outputId": "cec33270-6287-4fc9-82a3-6b71471c1ab6" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cbc 2.10.7: \b\b\b\b\b\b\b\b\b\b\b\bcbc 2.10.7: optimal solution; objective 150\n", "0 simplex iterations\n", "\n", "t = 0\n", "\n", "w[USD,0] = 0.00 \n", "w[EUR,0] = 100.00 \n", "w[JPY,0] = 0.00 \n", "\n", "t = 1\n", "\n", "EUR -> USD Convert 100 EUR to 200.0 USD\n", "\n", "w[USD,1] = 200.00 \n", "w[EUR,1] = -0.00 \n", "w[JPY,1] = 0.00 \n", "\n", "t = 2\n", "\n", "USD -> JPY Convert 200 USD to 20000.0 JPY\n", "\n", "w[USD,2] = 0.00 \n", "w[EUR,2] = 0.00 \n", "w[JPY,2] = 20000.00 \n", "\n", "t = 3\n", "\n", "JPY -> EUR Convert 20000.00000000001 JPY to 150.00000000000009 EUR\n", "\n", "w[USD,3] = 0.00 \n", "w[EUR,3] = 150.00 \n", "w[JPY,3] = 0.00 \n", "100\n", "150.0000000000001\n" ] } ], "source": [ "def arbitrage(T, df, R=\"EUR\"):\n", " m = AMPL()\n", " m.read(\"arbitrage.mod\")\n", "\n", " T0 = list(range(0, T + 1))\n", " T1 = list(range(1, T + 1))\n", " NODES = df.index\n", " ARCS = [(i, j) for i in NODES for j in NODES if i != j]\n", "\n", " m.set[\"T0\"] = T0\n", " m.set[\"T1\"] = T1\n", " m.set[\"NODES\"] = NODES\n", " m.set[\"ARCS\"] = ARCS\n", " m.param[\"T\"] = T\n", " m.param[\"R\"] = R\n", " m.param[\"a\"] = df\n", "\n", " m.solve(solver=SOLVER)\n", " assert m.solve_result == \"solved\", m.solve_result\n", "\n", " x = m.var[\"x\"].to_dict()\n", " w = m.var[\"w\"].to_dict()\n", "\n", " for t in T0:\n", " print(f\"\\nt = {t}\\n\")\n", " if t >= 1:\n", " for i, j in ARCS:\n", " if x[i, j, t] > 0:\n", " print(\n", " f\"{j} -> {i} Convert {x[i, j, t]} {j} to {df.loc[i,j]*x[i,j,t]} {i}\"\n", " )\n", " print()\n", "\n", " for i in NODES:\n", " print(f\"w[{i},{t}] = {w[i, t]:9.2f} \")\n", "\n", " return m\n", "\n", "\n", "m = arbitrage(3, df, \"EUR\")\n", "w = m.var[\"w\"].to_dict()\n", "print(w[\"EUR\", 0])\n", "print(w[\"EUR\", 3])" ] }, { "cell_type": "markdown", "metadata": { "id": "vArKbEvA1E6u" }, "source": [ "## Display graph" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " 100 EUR -> 200 USD -> 20000 JPY -> 150.0000000000001 EUR\n" ] }, { "data": { "image/png": "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hfTSSy+pXbt2KlmypMHEwK0olMB9sNls6tGjh7Zt26Yff/zxtlMEALhfXbp0UWRkpL777ju5u7vr9OnT+vTTT7VgwQI99thjeuutt3Tq1CkdPXpUsbGx2rlzp+nIwE24KQe4RzabTZ9++qnGjRunyZMnUyYBpJnRo0dr7dq1cnd315o1a9S6dWsVKFBAixYtuukO70uXLql06dLatGmTqlWrZjAxcDOu7gXuUXBwsD777DONHj1aHTt2NB0HgBPx8vJSgwYNdO3aNX322Wdq0qSJduzYoQYNGshms6UsS3b9+nX5+/vr77//NpwYuBmFErgHX375pQYMGKDg4GD16NHDdBwATio0NFRHjhxRmzZtlDt3biUlJclisaRcrz1nzhwdPXpUFSpUMBsU+A9OeQN3MXHiRH344Yfq16+fPv30U9NxADixmJgY5cmTRy+99JIkpRTJvXv3avr06Vq5cqWGDx+uMmXKmIwJ3IKbcoBUfPPNN2rbtq169uypL7/88palggAgreXLl0/t2rVT27Zt9ffff2vRokXat2+fkpOT9frrr+vdd99lwwQ4HAolcAcLFixQy5Yt1aFDB02cOJEyCSBDLF68WFOmTFFoaKg8PT1VsWJFlStXTm+//baeffZZWa1WXblyRWFhYXriiSdMxwUkUSiB21q2bJmaNm2qli1baubMmexOASBDJSYm6pdfflGePHnk5uam0qVLKyIiQsuWLdOqVau0ZcsW5cyZUy+88II6dOig1157zXRkuDgKJfAfa9euVcOGDdWwYUPNnz//lsXLASCjrVmzRmPHjtWRI0f0xBNPqGvXrrp+/bp++OEHLVy4UJGRkaYjwsVRKIF/2bJli+rUqaMaNWpo0aJFrDUJwJgbW7zOnTtXHTt21IsvvqjAwMCUG3ZuePzxx9WnTx+1adPGUFKAZYOAFLt27VK9evVUuXJlLVy4kDIJwCiLxaLz588rMDBQvXv31oYNG1LK5LVr1yRJBw8eVHx8vLJmzWoyKkChBCRp3759ql27tp555hktW7ZMPj4+piMBgH7++We5u7urWbNmkv6/SPr6+kr6ZyUKSXruueeM5ANu4OIwuLw//vhDNWvW1GOPPaZVq1alfKMGANOyZcumv//+WyVKlJD0/0Vy48aN6tevn/744w/NmDFDxYsXN5gS4BpKuLi//vpLVapUUeHC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+fLltX///lse//ff3AICAtS6dWs1atRI2bNnz8h4AACkGZvNphdffFFJSUnavXs3U0onQaE07NSpUypRosRNj92YRj711FNq06aNmjVrpkKFCpkJCABAGtu8ebOqVaumpUuXqlGjRqbjIA1QKA3r27evRowYkfL7EiVKqE2bNmrZsqUeeughg8kAAEg/1atX17lz5/Tbb7/d9bIvOL7br1ODDLNnzx55eHjo3XffVbt27fTcc88x/gcAOL3g4GC98MILWrBggVq2bGk6DuzkUBPK2MQkXbc6TJyMYbPJw82i7N6eppMAAJChGjZsqAMHDujgwYPy9OTnYGbmMIUyNjFJ609EmY5hTM2S+ZXNi4ExAMB1/P7776pQoYImT56sDh06mI4DOzjMskEuN5n8D1f//AAA11O+fHk1a9ZMQUFBio+PNx0HdnCYQgkAAFzP4MGDdfbsWU2ePNl0FNiBQgkAAIx5+OGH9c4772jYsGGKjY01HQcPiEIJAACMGjhwoGJiYjR27FjTUfCAKJQAAMCoYsWK6f3339fnn3+u6Oho03HwACiUAADAuE8//VTXr1/X559/bjoKHgCFEgAAGFewYEF1795dY8eOVWRkpOk4uE8USgAA4BA++ugjeXp6atiwYaaj4D5RKAEAgEPInTu3PvzwQ02ePFlhYWGm4+A+UCgBAIDD6N69u3LmzKmgoCDTUXAfKJQAAMBhZM+eXZ988olmzpypI0eOmI6De0ShBAAADqVTp04qXLiwBg0aZDoK7hGFEgAAOBQfHx8NGDBACxYs0O+//246Du4BhRIAADictm3bqlSpUhowYIDpKLgHFEoAAOBwPD09NXjwYK1YsUI//fST6Ti4C4vNZrOZDiFJ0fHXtfnUBdMxjHm1eD7l9vE0HQMAAIeRnJysJ598UoUKFdLGjRtNx0EqmFACAACH5O7urqCgIIWEhGjz5s2m4yAVTCgdBBNKAABuZbPZ9Pzzz8vT01M7duyQxWIxHQm3wYQSAAA4LIvFouDgYO3atUurV682HQd3wITSQTChBADg9mw2m1555RXFxMRo3759cnNjHuZo+C8CAAAc2o0p5W+//aZFixaZjoPbYELpIJhQAgCQutdee03Hjh3TgQMH5OHhYToO/oUJJQAAyBSGDh2qv/76S3PmzDEdBf/hNBPKTUu+04RPe97x+eELVipX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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def display_graph(m):\n", " m_w = m.var[\"w\"].to_dict()\n", " m_x = m.var[\"x\"].to_dict()\n", "\n", " T0 = m.set[\"T0\"].to_list()\n", " T1 = m.set[\"T1\"].to_list()\n", " NODES = m.set[\"NODES\"].to_list()\n", " ARCS = m.set[\"ARCS\"].to_list()\n", "\n", " path = []\n", "\n", " for t in T0:\n", " for i in NODES:\n", " if m_w[i, t] >= 1e-6:\n", " path.append(f\"{m_w[i, t]} {i}\")\n", " path = \" -> \".join(path)\n", " print(\"\\n\", path)\n", "\n", " G = nx.DiGraph()\n", " for i in NODES:\n", " G.add_node(i)\n", " nodelist = set()\n", " edge_labels = dict()\n", "\n", " for t in T1:\n", " for i, j in ARCS:\n", " if m_x[i, j, t] > 0.1:\n", " nodelist.add(i)\n", " nodelist.add(j)\n", " y = m_w[j, t - 1]\n", " x = m_w[j, t]\n", " G.add_edge(j, i)\n", " edge_labels[(j, i)] = df.loc[i, j]\n", "\n", " nodelist = list(nodelist)\n", " pos = nx.spring_layout(G)\n", " nx.draw(\n", " G,\n", " pos,\n", " with_labels=True,\n", " node_size=2000,\n", " nodelist=nodelist,\n", " node_color=\"lightblue\",\n", " node_shape=\"s\",\n", " arrowsize=20,\n", " label=path,\n", " )\n", " nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)\n", "\n", "\n", "display_graph(m)" ] }, { "cell_type": "markdown", "metadata": { "id": "bT4Wc81yx3aQ" }, "source": [ "## FOREX data\n", "\n", "https://www.bloomberg.com/markets/currencies/cross-rates\n", "\n", "https://www.tradingview.com/markets/currencies/cross-rates-overview-prices/" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 300 }, "executionInfo": { "elapsed": 145, "status": "ok", "timestamp": 1647604159358, "user": { "displayName": "Jeffrey Kantor", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gg_n8V7bVINy02QRuRgOoMo11Ri7NKU3OUKdC1bkQ=s64", "userId": "09038942003589296665" }, "user_tz": 240 }, "id": "fl_3XoLyV3Yb", "outputId": "0877b5b2-3998-4d71-e340-0a624984a1ec" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
USDEURJPYGBPCHFCADAUDHKD
USD1.00001.10960.00841.31481.06770.79150.73760.1279
EUR0.90121.00000.00761.18490.96220.71330.66470.1153
JPY118.6100131.60971.0000155.9484126.638993.881687.486715.1724
GBP0.76060.84390.00641.00000.81210.60200.56100.0973
CHF0.93661.03930.00791.23141.00000.74130.69080.1198
CAD1.26341.40190.01071.66111.34891.00000.93190.1616
AUD1.35571.50430.01141.78251.44751.07311.00000.1734
HKD7.81758.67430.065910.27848.34676.18775.76621.0000
\n", "
" ], "text/plain": [ " USD EUR JPY GBP CHF CAD AUD HKD\n", "USD 1.0000 1.1096 0.0084 1.3148 1.0677 0.7915 0.7376 0.1279\n", "EUR 0.9012 1.0000 0.0076 1.1849 0.9622 0.7133 0.6647 0.1153\n", "JPY 118.6100 131.6097 1.0000 155.9484 126.6389 93.8816 87.4867 15.1724\n", "GBP 0.7606 0.8439 0.0064 1.0000 0.8121 0.6020 0.5610 0.0973\n", "CHF 0.9366 1.0393 0.0079 1.2314 1.0000 0.7413 0.6908 0.1198\n", "CAD 1.2634 1.4019 0.0107 1.6611 1.3489 1.0000 0.9319 0.1616\n", "AUD 1.3557 1.5043 0.0114 1.7825 1.4475 1.0731 1.0000 0.1734\n", "HKD 7.8175 8.6743 0.0659 10.2784 8.3467 6.1877 5.7662 1.0000" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# data extracted 2022-03-17\n", "\n", "bloomberg = \"\"\"\n", "\tUSD\tEUR\tJPY\tGBP\tCHF\tCAD\tAUD\tHKD\n", "USD\t-\t1.1096\t0.0084\t1.3148\t1.0677\t0.7915\t0.7376\t0.1279\n", "EUR\t0.9012\t-\t0.0076\t1.1849\t0.9622\t0.7133\t0.6647\t0.1153\n", "JPY\t118.6100\t131.6097\t-\t155.9484\t126.6389\t93.8816\t87.4867\t15.1724\n", "GBP\t0.7606\t0.8439\t0.0064\t-\t0.8121\t0.6020\t0.5610\t0.0973\n", "CHF\t0.9366\t1.0393\t0.0079\t1.2314\t-\t0.7413\t0.6908\t0.1198\n", "CAD\t1.2634\t1.4019\t0.0107\t1.6611\t1.3489\t-\t0.9319\t0.1616\n", "AUD\t1.3557\t1.5043\t0.0114\t1.7825\t1.4475\t1.0731\t-\t0.1734\n", "HKD\t7.8175\t8.6743\t0.0659\t10.2784\t8.3467\t6.1877\t5.7662\t-\n", "\"\"\"\n", "\n", "\n", "df = pd.read_csv(io.StringIO(bloomberg.replace(\"-\", \"1.0\")), sep=\"\\t\", index_col=0)\n", "display(df)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "executionInfo": { "elapsed": 145, "status": "ok", "timestamp": 1647604160624, "user": { "displayName": "Jeffrey Kantor", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14Gg_n8V7bVINy02QRuRgOoMo11Ri7NKU3OUKdC1bkQ=s64", "userId": "09038942003589296665" }, "user_tz": 240 }, "id": "KSJR6u-bW95v", "outputId": "e048ce29-74bd-4fba-dc7e-b3058e67e275" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cbc 2.10.7: \b\b\b\b\b\b\b\b\b\b\b\bcbc 2.10.7: optimal solution; objective 100.451402\n", "0 simplex iterations\n", "\n", "t = 0\n", "\n", "w[USD,0] = 100.00 \n", "w[EUR,0] = 0.00 \n", "w[JPY,0] = 0.00 \n", "w[GBP,0] = 0.00 \n", "w[CHF,0] = 0.00 \n", "w[CAD,0] = 0.00 \n", "w[AUD,0] = 0.00 \n", "w[HKD,0] = 0.00 \n", "\n", "t = 1\n", "\n", "USD -> JPY Convert 100 USD to 11861.0 JPY\n", "\n", "w[USD,1] = 0.00 \n", "w[EUR,1] = 0.00 \n", "w[JPY,1] = 11861.00 \n", "w[GBP,1] = 0.00 \n", "w[CHF,1] = 0.00 \n", "w[CAD,1] = 0.00 \n", "w[AUD,1] = 0.00 \n", "w[HKD,1] = 0.00 \n", "\n", "t = 2\n", "\n", "GBP -> JPY Convert 2.399951029481301e-13 GBP to 3.742685231259617e-11 JPY\n", "AUD -> GBP Convert 2.851001950900435e-13 AUD to 1.599412094455144e-13 GBP\n", "JPY -> CAD Convert 11861 JPY to 126.91269999999999 CAD\n", "CAD -> AUD Convert 2.65817100640753e-13 CAD to 2.85248330697592e-13 AUD\n", "AUD -> HKD Convert 1.426981268386952e-13 AUD to 8.228259389772843e-13 HKD\n", "\n", "w[USD,2] = 0.00 \n", "w[EUR,2] = 0.00 \n", "w[JPY,2] = -0.00 \n", "w[GBP,2] = 0.00 \n", "w[CHF,2] = 0.00 \n", "w[CAD,2] = 126.91 \n", "w[AUD,2] = 0.00 \n", "w[HKD,2] = 0.00 \n", "\n", "t = 3\n", "\n", "CAD -> USD Convert 126.9127 CAD to 100.45140205 USD\n", "GBP -> EUR Convert 2.391852144845997e-14 GBP to 2.834105606428022e-14 EUR\n", "EUR -> CHF Convert 2.834105606428022e-14 EUR to 2.945485956760643e-14 CHF\n", "JPY -> CAD Convert 2.832313318459672e-12 JPY to 3.0305752507518485e-14 CAD\n", "\n", "w[USD,3] = 100.45 \n", "w[EUR,3] = 0.00 \n", "w[JPY,3] = 0.00 \n", "w[GBP,3] = 0.00 \n", "w[CHF,3] = 0.00 \n", "w[CAD,3] = 0.00 \n", "w[AUD,3] = 0.00 \n", "w[HKD,3] = 0.00 \n" ] } ], "source": [ "m = arbitrage(3, df, \"USD\")" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " 100 USD -> 11861 JPY -> 126.9127 CAD -> 100.45140205 USD\n" ] }, { "data": { "image/png": "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atiwYapZs2YBpQMKt4EDB+rs2bPau3ev0VGAP0ShBHDPli9frmeffVZeXl6KjIxU06ZN//T5FotFbm4sjAB349tvv9WgQYMUFxenunXrGh0H+F38zg7grqWmpio0NFRDhgzRq6++qoSEhN+Uyd/7b1XKJHD3evfuLX9/fy1YsMDoKMAf4golgLuWlJSkmjVr6oknntDHH38sSZozZ468vb1Vs2ZNtWvXzuCEgHN57LHHtHPnTsXGxspkMhkdB/gNCiWAu5KTkyN3d3fNmDFDc+bMUefOnRUZGakaNWro7Nmzun37tgYPHmwrmgDst379egUFBWnfvn1q3ry50XGA36BQAvhTV65cUXx8vFq0aCGLxSKTyWS7QtK2bVslJSVpwoQJ6t+/v27cuKFdu3YpPDxcy5YtU2hoqKxWK1dUADtlZ2ercuXKMpvNmj59utFxgN+gUAL4Q1988YWeeeYZeXl56erVq/Lx8ZH08x9uHh4eOnTokPbu3athw4blOt09ePBgXb58WZs3bzYqOuB0Ro0apcWLF+unn36Su7u70XGAXNghD+A3LBaLFi5cqH//+98aN26cKleurJdfflnSz4dtPDw8JElNmzbVk08+matMWq1WWa1WeXl56datW797OAfA3TObzbp48aK2bNlidBTgNyiUAH7Dzc1NpUqVUlhYmMaMGaPJkyfrs88+08GDB2UymXKVxP9dzj5//rySkpI0aNAgFS1alOVuII+0atVKNWvWVEREhNFRgN9gyRuAJCk5OVllypSxFcBf7328fv26wsPDdfXqVe3evfs3r01PT9fx48d1+vRpjR8/XnXq1NG8efNUoUKFAv0MgLObMGGCZs2apaSkJBUpUsToOIANVygBF7d161bdf//9GjRokDp06KB169YpPT1dJpNJFotFklS8eHFNnDhRR44c0RdffCEp930mjx07pilTpmjMmDF67rnntGbNGsokkA/MZrOuX7+u1atXGx0FyIUrlIALmz9/vsaPH68nn3xSLVu21NKlS7Vq1SqNHj1aY8eOlfT/022ysrI0YcIEffHFF0pISJCfn5+uX7+uIkWKyMvLS3v37lXDhg3l6+tr8KcCnFuzZs1Up04dLVq0yOgogA2FEnBhjzzyiEqUKKFZs2bZHuvcubNiY2P16aefqn///rnGJf7000/q1q2bOnXqpK5du2rKlCl677331Lt3b6M+AuByPvzwQ02YMEFJSUny9/c3Og4giSVvwKUcOXJEy5YtkyTdvHlTmzZtso1MTE9PlyTbrODZs2frypUrcnNzsy19V6lSRY888ojmzJmjxx57TP369aNMAgUsLCxMt2/f1vLly42OAthQKAEXkJaWpoceekhNmzbVwoULlZGRoWLFiumBBx7QP//5TyUmJsrHx0e7du3S0aNHFRISouTkZO3Zs0fSz6e+b926pUmTJunvf/+7hg4dqgsXLujNN980+JMBrqdy5crq2LEjp73hUCiUgJObNm2aypQpo8zMTIWGhurcuXPy9vaWJL399tv66aef1LFjRzVp0kTt27fXgAED9PnnnyshIUFJSUm290lOTlZKSopWr16t//znPypRooRBnwiA2WzWhg0bcv07ChiJPZSAkzp79qyCg4N16dIlffLJJxo4cKAWL16sUaNGaevWrapdu7Yk6dSpUzpw4IBOnjypJ598Uvfdd58kqXHjxnr44Yc1btw4Iz8GgN9x5coV3XfffZo2bZpeeOEFo+MA8jA6AID8YbVa9cQTT+jZZ5+Vp6en7XF3d3elpaXZvq5Tp47q1KmT67Xbtm1TWlqaevXqVWB5Ady50qVLq2fPnoqIiKBQwiGw5A04IavVqmrVqmnkyJHy9PRUTk6OJKl79+5KSUnRqVOnJMl22EaSbt++rYSEBK1YsULPPvus2rZtqxo1ajA6EXBQZrNZu3fv1pkzZ4yOAlAoAWf0v+MO3d3dJUnZ2dlq0aKFdu3aJUm22wFJUkJCgqZPn67HH39c/fr109dffy0/Pz9GJwIOKjg4WL6+vlqwYIHRUQAKJVCYWSwW7du3T4mJiXf0/DJlykiSUlJSJMl25VL6+XZBjzzyiGJjY/X222/nfVgAecrX11f9+vXT/PnzWUmA4SiUQCH173//WxUqVNAjjzyiBg0a6N1339XZs2cl5V7K/sUv5bFr16767rvvJP3/lctftGjRQqVLl87f4ADyjNls1okTJ3TkyBGjo8DFUSiBQmjv3r167733NGXKFC1fvlwTJkzQnDlzNGnSJN26dSvXzch/8Ut5rFSpkvz8/HTixAkjogPIQ927d1eZMmW4JyUMR6EECqGdO3cqLS1Nw4YNU0BAgG32dkxMjD788EPb8369DPZLwaxataqOHj1a4JkB5D1PT08N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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display_graph(m)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 4 }