hhatefi

Curious about computing, modeling and analysis

Finding The Best Rate in Forex Graph

Currencies are traded in pairs by simultaneously buying one and selling the other. Each pair is associated with an exchange rate, which indicates the relative price of the first currency with respect to the second one. For instance pair EUR_USD with rate 1.2 shows every Euro values 1.2 US dollar. Let say you want to change your Euros to US dollars and want to get the best rate possible. One way is of course to change them directly to dollar with rate 1.2. You require to submit only one trade. But maybe, you get a better rate if you first sell the Euros and get some Japanese yens and then change the yens to US dollar. This includes two trades, which imposes the uncertainty coming from two order executions. In this post, I explain how to get the best rate between two currencies, possibly through some intermediate currency exchanges when the maximum number of trades is restricted.

Formulation and modeling

We are given a list of currency pairs with their associated bid and ask rates. For each pair, the bid rate is the price of selling one unit of the first currency with respect to the second. The ask rate is similar but for buying one unit of the first currency. With both bid and ask rates given, it is possible to model tradable currencies as a directed graph. In this graph, currencies are modeled as nodes which are connected by edges, provided that they are directly tradable. That is to say, a pair between currency \(C_1\) and \(C_2\) with bid rate \(b\) and ask rate \(a\) is simply modeled by an edge from \(C_1\) to \(C_2\) with weight \(b\) and an edge from \(C_2\) to \(C_1\) with weight \(\frac{1}{a}\). As an example, assume EUR_USD is traded with bid rate 1.2 and ask rate 1.4, then the edge between EUR to USD has weight 1.2 and the edge between USD to EUR has weight \(\frac{1}{1.4}=\frac{5}{7}\). The following example shows how to construct the graph, given the list of currency pairs.

pair bid ask
EUR_USD 1.21048 1.21090
EUR_GBP 0.87052 0.87113
EUR_CHF 1.07987 1.08110
GBP_USD 1.38998 1.39058
GBP_CHF 1.23988 1.24138
USD_CHF 0.89199 0.89280

The result is a directed graph with four nodes and 12 edges. Since all currencies are directly tradable, the graph is complete, i.e. each currency is connected to all others via a direct edge. The edges are, depending on their direction, associated either with the bid or with the ask rate. Their weights are computed as explained above.

Figure 1: The graph associated with the above table

Figure 1: The graph associated with the above table

Now assume we want to compute the rate from EUR to GBP through USD as the intermediate currency. That is equivalent to taking path \(\mathrm{EUR}\rightarrow\mathrm{USD}\rightarrow\mathrm{GBP}\) in the forex graph. The rate is computed by multiplying the rates of each edge along the path, which is \(0.87048=1.21048\times0.71912\). This value is the multiplicative distance from EUR to GBP via USD in the graph. In general, the rate between two currencies through a certain path coincides with multiplicative distance between them. The multiplicative distance from \(c_1\) to \(c_n\) through path \(c_1\rightarrow c_2\rightarrow\cdots\rightarrow c_n\) is computed by

\begin{equation*} \prod_{i=1}^{n-1}w(c_i,c_{i+1}) \end{equation*}

where \(w(c_i,c_{i+1})\) is the weight of the edge from \(c_i\) to \(c_{i+1}\), i.e. the direct rate of selling \(c_i\) and buying \(c_{i+1}\). This path composed of \(n-1\) consecutive trades. In practice we may want to restrict the number of trades, i.e. considering only paths up to a certain length. Each of those paths gives one rate, with the maximum one being the best rate. Formally speaking, for a given currency \(c\) and the maximum number of trades \(T\), we want to compute the maximum rate from \(c\) to any other currency by doing at most \(T\) trades. This is equivalent to the maximum multiplicative distance from \(c\) to any other currency considering the paths with length of at most \(T\).

Dynamic programming

The maximum multiplicative distance can be computed in a similar way as the shortest path in a graph. However, the length of paths, which is equivalent to the number of trades, is bounded. That is not usually the case in classical variations of shortest path problem. Moreover, the shortest path is indeed the minimum additive distance, which is different than the maximum bounded multiplicative distance needed here. In order to adapt shortest path computation to bounded multiplicative distance maximization, I use a variant of Bellman-Ford algorithm. The core of Bellman-Ford algorithm is a recursive formula which updates the shortest path iteratively. This formula is required to be adapted to multiplicative distance maximization as follows:

\begin{equation} \label{eq:rec} R_c(d,t+1)=\max_{(u,d)\in E}\left\{R_c(u,t)*w(u,d)\right\} \end{equation}

where \(R_c(d,t)\) is the maximum multiplicative distance from \(c\) to \(d\) over paths of length \(t\) and \(E\) is the set of edges in the forex graph. The idea is to extend the maximum multiplicative distance over paths of length \(t\) by attaching a single edge to it. It establishes the maximum multiplicative distance over paths of length \(t+1\). In trading world, we find all currencies that can be directly exchanged to \(d\), use them as the middle currency and choose the one that gives the best rate. The middle currency that gives the best result is the t-th vertex on the optimal path. By storing the middle currencies in each iteration, we can construct the optimal path. An implementation of the algorithm in python is given below.

The algorithm is basically computes the best rates according to the recursion described by \(\eqref{eq:rec}\). This operations is repeated \(T\) times, each time for all currencies in the graph. Therefore, the complexity of the algorithm is quadratic in the number of currencies and linear in the number of trades.

The forex graph is passed as variable graph, which stores the adjacency matrix of the graph. That is to say, graph[c][d] is the rate of exchanging currency c to d. Other inputs are the source currency src and the maximum number of trades T. As the output, it returns two tables both with T+1 rows. Each column is associated with a currency. The rates are stored in dist table, where dist[t,c] stores the best rate from src to c by doing t trades. The optimal path i.e. the middle currencies are stored in pre. For example, pre[t,c] indicates the middle currency right before c along the optimal path from src to c.

Conclusions

Forex trading rates can be aggregated and modeled by a graph. Doing so enables us to conduct certain analysis on the forex graph in order to answer some questions in the trading world. As an example, we have seen that an adaptation of shortest path algorithm can be used for computing the maximum rate between two currencies when there is an upper bound on the number of trades.