From a72b6a7fcc0d3c5a0c3aa5d19eaad49369204046 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 12:16:58 +0300 Subject: [PATCH 1/9] =?UTF-8?q?=D0=9F=D0=BE=D1=84=D0=B8=D0=BA=D1=81=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D0=BC=D0=B5=D1=81=D1=82=D0=B0=20=D0=B2=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/counter.py | 104 +++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 44 deletions(-) diff --git a/telegram/src/counter.py b/telegram/src/counter.py index c7b8500..5543eea 100644 --- a/telegram/src/counter.py +++ b/telegram/src/counter.py @@ -1,29 +1,50 @@ +from src.db_requests.offers import Offer + + def Counter(data: list): + """ + Поиск релазиован с помощью алгоритма поиска наибольшего пути + в ациклическом графе. Для этого нам нужно транспонировать исходный граф, + а потом, с помощью методом динамического программирования, найти наиболее + большой путь. Мы не будем явно транспонировать граф, мы изначально его зададим + в транспонированном виде. + """ + N = 71 INF = 100000000 + _fiat = {"RUB", "USD", "EUR", "CNY", "GBP"} + _crypto = {"USDT": 1, "BTC": 2, "BUSD": 3, "BNB": 4, "ETH": 5} + _market = {"binance": 1, "bybit": 2, "huobi": 3} + _deC = {1: "USDT", 2: "BTC", 3: "BUSD", 4: "BNB", 5: "ETH"} + _deM = {1: "binance", 2: "bybit", 3: "huobi"} + + class Coin: + def __init__(self, type, name): + self.type_of_coin = type + self.name = name + class LiteOffer: + """ + Оффер, подобный классу Offer.py, являющийся сжатой его версией. + Нужен для того, чтобы нормально инициализировать офферы в нашем графе. + """ + def __init__(self, big_offer): - self.receive_coin = big_offer.receive_coin - self.init_coin = big_offer.init_coin + self.receive_coin = Coin("receive", big_offer.receive_coin) + self.init_coin = Coin("init", big_offer.receive_coin) self.market = big_offer.market self.payment = big_offer.payment self.sell_buy = big_offer.sell_buy - self.price = float(big_offer.price) + self.price = big_offer.price self.maker_commission = big_offer.maker_commission self.taker_commission = big_offer.taker_commission - _fiat = {"RUB", "USD", "EUR", "CNY", "GBP"} - _crypto = {"USDT": 1, "BTC": 2, "BUSD": 3, "BNB": 4, "ETH": 5} - _market = {"binance": 1, "bybit": 2, "huobi": 3} - _deC = {1: "USDT", 2: "BTC", 3: "BUSD", 4: "BNB", 5: "ETH"} - _deM = {1: "binance", 2: "bybit", 3: "huobi"} - - def PosByOffer(offer: LiteOffer, type_of_offer: str): - offer_name = offer.receive_coin if type_of_offer == "receive" else offer.init_coin - if offer_name.upper() in _fiat: - return N - 1 if type_of_offer == "init" else 0 - return _crypto[offer_name] * 10 + _market[offer.market] + def PosByOffer(self, type_of_offer): + offer_name = offer.receive_coin.name if type_of_offer == "receive" else offer.init_coin.name + if offer_name.upper() in _fiat: + return N - 1 if type_of_offer == "init" else 0 + return _crypto[offer_name] * 10 + _market[offer.market] def Commission(offer_name): # комса указана в рублях @@ -34,29 +55,25 @@ def Commission(offer_name): else: return 0 - """ - Поиск релазиован с помощью алгоритма поиска наибольшего пути - в ациклическом графе. Для этого нам нужно транспонировать исходный граф, - а потом, с помощью методом динамического программирования, найти наиболее - большой путь. Мы не будем явно транспонировать граф, мы изначально его зададим - в транспонированном виде. - """ if len(data) == 0: return "Invalid input" + gr = [[] for i in range(N)] for offer in data: - lite_offer = LiteOffer(offer) - if lite_offer.receive_coin.upper() in _fiat: - gr[0].append(lite_offer) - elif lite_offer.receive_coin in _crypto.keys(): - gr[PosByOffer(lite_offer, "receive")].append(lite_offer) + edge_offer = LiteOffer(offer) + pos_to = edge_offer.PosByOffer("receive") + if edge_offer.receive_coin.name.upper() in _fiat: + gr[0].append(edge_offer) if edge_offer.sell_buy else gr[pos_to].append(edge_offer) + elif edge_offer.receive_coin.name in _crypto.keys(): + gr[pos_to].append(edge_offer) if edge_offer.sell_buy else gr[0].append(edge_offer) else: - print(lite_offer.init_coin, lite_offer.receive_coin, lite_offer.market, "<-INVALID COIN", offer.id) + print(edge_offer.init_coin.name, edge_offer.receive_coin.name, edge_offer.market, "<-INVALID COIN", + offer.id) for i in range(1, len(_crypto) + 1): for j in range(2, len(_market) + 1): for k in range(1, j): modificate_offer = LiteOffer(data[0]) - modificate_offer.init_coin, modificate_offer.receive_coin, modificate_offer.price, modificate_offer.market = \ + modificate_offer.init_coin.name, modificate_offer.receive_coin.name, modificate_offer.price, modificate_offer.market = \ _deC[i], _deC[i], Commission(_deC[i]), _deM[k] offer_between_markets_1 = LiteOffer(modificate_offer) gr[i * 10 + j].append(offer_between_markets_1) @@ -64,15 +81,15 @@ def Commission(offer_name): offer_between_markets_2 = LiteOffer(modificate_offer) gr[i * 10 + k].append(offer_between_markets_2) # здесь в поле маркет указано, куда мы переводим монеты - prev = [None for i in range(N)] + prev = [LiteOffer(Offer()) for i in range(N)] dp = [-INF for i in range(N)] dp[0] = 0 def dfs(v: int, p: int): for u in gr[v]: - pos = PosByOffer(u, "init") + pos = u.PosByOffer("init") cur_commission = (min(u.taker_commission, u.maker_commission)) / 100 - if u.receive_coin in _crypto.keys(): + if u.receive_coin.name in _crypto.keys(): if dp[pos] == -INF: dp[pos] = dp[v] + u.price - u.price * cur_commission prev[pos] = u @@ -92,19 +109,18 @@ def dfs(v: int, p: int): dfs(0, -1) ans = str() pos = N - 1 - for i in range(3): - try: - cur_offer = prev[pos] - if cur_offer.init_coin != cur_offer.receive_coin: - ans += "Buy " if cur_offer.sell_buy else "Sell " - ans += "Taker " if cur_offer.maker_commission > cur_offer.taker_commission else "Maker " - ans += cur_offer.market + " " + cur_offer.init_coin + " " + cur_offer.receive_coin + " " - ans += cur_offer.payment + " -> " - else: - ans += cur_offer.init_coin + " Transfer to next market -> " - pos = PosByOffer(cur_offer, "receive") - except Exception: - break + step = 0 + while pos != 0 and step < 4: + step += 1 + cur_offer = prev[pos] + if cur_offer.init_coin.name != cur_offer.receive_coin.name: + ans += "Buy " if cur_offer.sell_buy else "Sell " + ans += "Taker " if cur_offer.maker_commission > cur_offer.taker_commission else "Maker " + ans += cur_offer.market + " " + cur_offer.init_coin.name + " " + cur_offer.receive_coin.name + " " + ans += cur_offer.payment + " -> " + else: + ans += cur_offer.init_coin.name + " Transfer to next market -> " + pos = cur_offer.PosByOffer("receive") if dp[N - 1] >= 0: ans += "PROFITABLY!" else: From 37eaf899df70e6852fc36c1f0cc32f5b55514151 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 13:41:36 +0300 Subject: [PATCH 2/9] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D0=B8=D0=BB=D0=B2=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/src/Dockerfile b/telegram/src/Dockerfile index 26868d2..285245b 100644 --- a/telegram/src/Dockerfile +++ b/telegram/src/Dockerfile @@ -4,4 +4,4 @@ ENV PYTHONUNBUFFERED=1 COPY . /src RUN pip install --upgrade pip -RUN pip install -r src/requirements.txt \ No newline at end of file +RUN pip install -r telegram/src/requirements.txt \ No newline at end of file From 8d19ecda58808a9ddeca5054d49105026f0ad4c2 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 13:49:49 +0300 Subject: [PATCH 3/9] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D0=B8=D0=BB=D0=B2=D0=B5=D0=B9=202=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/src/Dockerfile b/telegram/src/Dockerfile index 285245b..526d86c 100644 --- a/telegram/src/Dockerfile +++ b/telegram/src/Dockerfile @@ -4,4 +4,4 @@ ENV PYTHONUNBUFFERED=1 COPY . /src RUN pip install --upgrade pip -RUN pip install -r telegram/src/requirements.txt \ No newline at end of file +RUN pip install -r requirements.txt \ No newline at end of file From 673e261f68e9c6004f0f43356504926694cc86cc Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 13:53:53 +0300 Subject: [PATCH 4/9] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D0=B8=D0=BB=D0=B2=D0=B5=D0=B9=202=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/telegram/src/Dockerfile b/telegram/src/Dockerfile index 526d86c..70b4e49 100644 --- a/telegram/src/Dockerfile +++ b/telegram/src/Dockerfile @@ -4,4 +4,5 @@ ENV PYTHONUNBUFFERED=1 COPY . /src RUN pip install --upgrade pip +RUN ls -l RUN pip install -r requirements.txt \ No newline at end of file From 4ea709c04078ca1d5ab120bcb0bb4e846c544f68 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 13:56:22 +0300 Subject: [PATCH 5/9] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D0=B8=D0=BB=D0=B2=D0=B5=D0=B9=203=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/src/Dockerfile b/telegram/src/Dockerfile index 70b4e49..15e2827 100644 --- a/telegram/src/Dockerfile +++ b/telegram/src/Dockerfile @@ -4,5 +4,5 @@ ENV PYTHONUNBUFFERED=1 COPY . /src RUN pip install --upgrade pip -RUN ls -l +RUN find -name requirements.txt RUN pip install -r requirements.txt \ No newline at end of file From 3a221624297a8c75433ab2ec4cab2336e6ebf1f5 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 13:58:44 +0300 Subject: [PATCH 6/9] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D0=B8=D0=BB=D0=B2=D0=B5=D0=B9=204=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/telegram/src/Dockerfile b/telegram/src/Dockerfile index 15e2827..0a44037 100644 --- a/telegram/src/Dockerfile +++ b/telegram/src/Dockerfile @@ -4,5 +4,4 @@ ENV PYTHONUNBUFFERED=1 COPY . /src RUN pip install --upgrade pip -RUN find -name requirements.txt -RUN pip install -r requirements.txt \ No newline at end of file +RUN pip install -r ./src/telegram/src/requirements.txt \ No newline at end of file From a2999dbed6f230063babe02ca32ce22280c38180 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 14:11:28 +0300 Subject: [PATCH 7/9] =?UTF-8?q?=D0=9F=D0=BE=D1=84=D0=B8=D0=BA=D1=81=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/counter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram/src/counter.py b/telegram/src/counter.py index 5543eea..1dca200 100644 --- a/telegram/src/counter.py +++ b/telegram/src/counter.py @@ -41,10 +41,10 @@ def __init__(self, big_offer): self.taker_commission = big_offer.taker_commission def PosByOffer(self, type_of_offer): - offer_name = offer.receive_coin.name if type_of_offer == "receive" else offer.init_coin.name + offer_name = self.receive_coin.name if type_of_offer == "receive" else self.init_coin.name if offer_name.upper() in _fiat: return N - 1 if type_of_offer == "init" else 0 - return _crypto[offer_name] * 10 + _market[offer.market] + return _crypto[offer_name] * 10 + _market[self.market] def Commission(offer_name): # комса указана в рублях From e36469131e136f4b4269b425ca93512d8fe2d394 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 14:14:44 +0300 Subject: [PATCH 8/9] =?UTF-8?q?=D0=92=D0=B5=D1=80=D0=BD=D1=83=D0=BB=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D1=8B=D0=B9=20=D0=B4=D0=BE=D0=BA=D0=B5?= =?UTF-8?q?=D1=80=D1=84=D0=B0=D0=B9=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/src/Dockerfile b/telegram/src/Dockerfile index 0a44037..26868d2 100644 --- a/telegram/src/Dockerfile +++ b/telegram/src/Dockerfile @@ -4,4 +4,4 @@ ENV PYTHONUNBUFFERED=1 COPY . /src RUN pip install --upgrade pip -RUN pip install -r ./src/telegram/src/requirements.txt \ No newline at end of file +RUN pip install -r src/requirements.txt \ No newline at end of file From ca9c74d40064b10d3fa08669fb8f7fec0b9cfc18 Mon Sep 17 00:00:00 2001 From: vaZZZy1 Date: Sun, 15 Jan 2023 18:13:21 +0300 Subject: [PATCH 9/9] =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BA=D0=B0=D1=83=D0=BD=D1=82=D0=B5=D1=80.=20=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=B2=D1=81=D0=B5=20=D0=B5=D1=89=D0=B5=20=D0=BD=D0=B5?= =?UTF-8?q?=20=D1=80=D0=B0=D0=B1=D0=BE=D0=B0=D1=82=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram/src/counter.py | 44 ++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/telegram/src/counter.py b/telegram/src/counter.py index 1dca200..8d76b7c 100644 --- a/telegram/src/counter.py +++ b/telegram/src/counter.py @@ -20,7 +20,7 @@ def Counter(data: list): _deM = {1: "binance", 2: "bybit", 3: "huobi"} class Coin: - def __init__(self, type, name): + def __init__(self, type, name : str): self.type_of_coin = type self.name = name @@ -31,8 +31,8 @@ class LiteOffer: """ def __init__(self, big_offer): - self.receive_coin = Coin("receive", big_offer.receive_coin) - self.init_coin = Coin("init", big_offer.receive_coin) + self.receive_coin = str(big_offer.receive_coin) + self.init_coin = str(big_offer.init_coin) self.market = big_offer.market self.payment = big_offer.payment self.sell_buy = big_offer.sell_buy @@ -41,7 +41,7 @@ def __init__(self, big_offer): self.taker_commission = big_offer.taker_commission def PosByOffer(self, type_of_offer): - offer_name = self.receive_coin.name if type_of_offer == "receive" else self.init_coin.name + offer_name = str(self.receive_coin) if type_of_offer == "receive" else str(self.init_coin) if offer_name.upper() in _fiat: return N - 1 if type_of_offer == "init" else 0 return _crypto[offer_name] * 10 + _market[self.market] @@ -62,18 +62,18 @@ def Commission(offer_name): for offer in data: edge_offer = LiteOffer(offer) pos_to = edge_offer.PosByOffer("receive") - if edge_offer.receive_coin.name.upper() in _fiat: + if edge_offer.receive_coin.upper() in _fiat: gr[0].append(edge_offer) if edge_offer.sell_buy else gr[pos_to].append(edge_offer) - elif edge_offer.receive_coin.name in _crypto.keys(): + elif edge_offer.receive_coin in _crypto.keys(): gr[pos_to].append(edge_offer) if edge_offer.sell_buy else gr[0].append(edge_offer) else: - print(edge_offer.init_coin.name, edge_offer.receive_coin.name, edge_offer.market, "<-INVALID COIN", + print(edge_offer.init_coin, edge_offer.receive_coin, edge_offer.market, "<-INVALID COIN", offer.id) for i in range(1, len(_crypto) + 1): for j in range(2, len(_market) + 1): for k in range(1, j): modificate_offer = LiteOffer(data[0]) - modificate_offer.init_coin.name, modificate_offer.receive_coin.name, modificate_offer.price, modificate_offer.market = \ + modificate_offer.init_coin, modificate_offer.receive_coin, modificate_offer.price, modificate_offer.market = \ _deC[i], _deC[i], Commission(_deC[i]), _deM[k] offer_between_markets_1 = LiteOffer(modificate_offer) gr[i * 10 + j].append(offer_between_markets_1) @@ -89,19 +89,21 @@ def dfs(v: int, p: int): for u in gr[v]: pos = u.PosByOffer("init") cur_commission = (min(u.taker_commission, u.maker_commission)) / 100 - if u.receive_coin.name in _crypto.keys(): - if dp[pos] == -INF: + if u.receive_coin in _crypto.keys(): + if dp[pos] == -INF or dp[v] + u.price < dp[pos]: dp[pos] = dp[v] + u.price - u.price * cur_commission - prev[pos] = u - elif dp[v] + u.price < dp[pos]: - dp[pos] = dp[v] + u.price - u.price * cur_commission - prev[pos] = u - if p // 10 == v // 10: - prev[pos].market = _deM[p % 10] + prev[pos] = LiteOffer(u) + # if pos == N-1: + # print(u.receive_coin, u.init_coin, "in dfs") + if pos // 10 == v // 10: + print("im here") + prev[pos].market = _deM[v % 10] + ","+_deM[pos%10] else: if u.price - dp[v] > dp[pos]: dp[pos] = u.price - dp[v] - u.price * cur_commission - prev[pos] = u + prev[pos] = LiteOffer(u) + # if pos == N-1: + # print(u.receive_coin, u.init_coin, "in dfs") if p // 10 != v // 10 or v // 10 != pos // 10: dfs(pos, v) @@ -110,16 +112,18 @@ def dfs(v: int, p: int): ans = str() pos = N - 1 step = 0 + print("____________") while pos != 0 and step < 4: step += 1 cur_offer = prev[pos] - if cur_offer.init_coin.name != cur_offer.receive_coin.name: + if cur_offer.init_coin != cur_offer.receive_coin: ans += "Buy " if cur_offer.sell_buy else "Sell " ans += "Taker " if cur_offer.maker_commission > cur_offer.taker_commission else "Maker " - ans += cur_offer.market + " " + cur_offer.init_coin.name + " " + cur_offer.receive_coin.name + " " + ans += cur_offer.market + " " + cur_offer.init_coin + " " + cur_offer.receive_coin + " " ans += cur_offer.payment + " -> " else: - ans += cur_offer.init_coin.name + " Transfer to next market -> " + print(cur_offer.init_coin, cur_offer.receive_coin, cur_offer.market, pos) + ans += cur_offer.init_coin + " Transfer to next market -> " pos = cur_offer.PosByOffer("receive") if dp[N - 1] >= 0: ans += "PROFITABLY!"