bhftbootcamp / CcyConv.jl

CcyConv is a Julia package for performing currency conversions. It allows for direct and multi-step conversions using the latest exchange 💱 rates
MIT License
20 stars 3 forks source link

Closes 1 for pathfinding algo #6

Closed darthur11 closed 3 months ago

darthur11 commented 4 months ago

Pull request checklist

darthur11 commented 4 months ago

This MR adds pathfinder functions for max and min product

artememelin commented 4 months ago

Hi, @darthur11 !

I looked at your solution and, as far as I noticed, your algorithm solves the problem by searching through all possible paths in the graph

The algorithm really works and in one of the tests it was able to calculate a more optimal value.

However, the big disadvantage of this approach is that it becomes extremely ineffective on large graphs.

The following example generates a small graph like:

A1 -> B1 -> C3 -> ... -> Y1 -> Z1
|     |     |                  |
V     V     V                  V
A2 -> B2 -> ...
|     |
V     V
...
|
V
A9 -> B9 -> ...
using CcyConv

my_graph = FXGraph()
for (from_asset, to_asset) in zip('A':'Y', 'B':'Z')
    for (from_ind, to_ind) in zip(1:9, 2:10)
        append!(
            my_graph,
            [
                Price(string(from_asset, from_ind), string(from_asset, to_ind), 1.2),
                Price(string(from_asset, from_ind), string(to_asset, from_ind), 1.2),
            ],
        )
    end
end
my_graph

a_star_rate = conv_a_star(my_graph, "A1", "Z9")
# ConvRate("A1", "Z9", 410.18627024600187, CcyConv.AbstractPrice[Price("A1", "B1", 1.2), Price("B1", "C1", 1.2), Price("C1", "D1", 1.2), Price("D1", "E1", 1.2), Price("E1", "F1", 1.2), Price("F1", "G1", 1.2), Price("G1", "H1", 1.2), Price("H1", "I1", 1.2), Price("I1", "J1", 1.2), Price("J1", "K1", 1.2)  …  Price("U4", "V4", 1.2), Price("V4", "W4", 1.2), Price("W4", "X4", 1.2), Price("X4", "Y4", 1.2), Price("Y4", "Y5", 1.2), Price("Y5", "Y6", 1.2), Price("Y6", "Y7", 1.2), Price("Y7", "Y8", 1.2), Price("Y8", "Y9", 1.2), Price("Y9", "Z9", 1.2)])

length(a_star_rate.chain)

conv_max(fx, from, to) = fx(CcyConv.MyCtx(), your_max_alg, from, to)
conv_min(fx, from, to) = fx(CcyConv.MyCtx(), your_min_alg, from, to)

max_rate = conv_max(my_graph, "A1", "Z9")
min_rate = conv_min(my_graph, "A1", "Z9")

In this case, calculating the optimal path takes an extremely long time

darthur11 commented 4 months ago

Thanks for review, @artememelin .

Basically I've decided to use this method which searches through all available paths because it's hard to have a very long path in the market like crypto, when you have a lot of changes in a very short amount of time.

Overall, I agree and will find a better algorithm for this task.

gryumov commented 3 months ago

I'll close the PR until we revise the algorithm.