From 7b994d4391ff24e8c5a6f7f59e548b984493efe2 Mon Sep 17 00:00:00 2001 From: barak manos <> Date: Tue, 28 May 2024 23:28:10 +0300 Subject: [PATCH] Generate a price-map for the optimizer based on the significance of the exchange which the price is taken from (B2, then B3, then U2, then U3, then all the rest with equal significance). --- fastlane_bot/modes/base.py | 25 +++++++++++++++++-------- fastlane_bot/modes/base_pairwise.py | 6 +----- fastlane_bot/modes/base_triangle.py | 17 +---------------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/fastlane_bot/modes/base.py b/fastlane_bot/modes/base.py index 4c0ee70c4..def37d89a 100644 --- a/fastlane_bot/modes/base.py +++ b/fastlane_bot/modes/base.py @@ -57,19 +57,28 @@ def get_profit(self, src_token: str, optimization, trade_instructions_df): def calculate_profit(self, src_token: str, src_profit: float) -> Decimal: if src_token not in [self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS]: - price = get_reliable_price(self.CCm, self.sort_order, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, src_token) - assert price is not None, f"Failed to get conversion rate for {src_token} and {self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS}" + price = self.find_reliable_price(self.CCm, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, src_token) + assert price is not None, f"No conversion rate for {self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS} and {src_token}" return Decimal(str(src_profit)) / Decimal(str(price)) return Decimal(str(src_profit)) + def get_params(self, cc, dst_tokens, src_token): + pstart = {src_token: 1} + for dst_token in dst_tokens: + if dst_token != src_token: + pstart[dst_token] = self.find_reliable_price(cc, dst_token, src_token) + if pstart[dst_token] is None: + return None + return {"pstart": pstart} + + def find_reliable_price(self, cc, dst_token, src_token): + list1 = [{"exchange": curve.params.exchange, "price": curve.p / 1} for curve in cc.bytknx(dst_token).bytkny(src_token).curves] + list2 = [{"exchange": curve.params.exchange, "price": 1 / curve.p} for curve in cc.bytknx(src_token).bytkny(dst_token).curves] + items = sorted(list1 + list2, key = lambda item: self.sort_order.get(item["exchange"], float("inf"))) + return items[0]["price"] if len(items) > 0 else None + def is_net_change_small(trade_instructions_df) -> bool: try: return max(trade_instructions_df.iloc[-1]) < 1e-4 except Exception: return False - -def get_reliable_price(CCm, sort_order, dst_token, src_token): - list1 = [{"exchange": curve.params.exchange, "price": curve.p / 1} for curve in CCm.bytknx(dst_token).bytkny(src_token).curves] - list2 = [{"exchange": curve.params.exchange, "price": 1 / curve.p} for curve in CCm.bytknx(src_token).bytkny(dst_token).curves] - items = sorted(list1 + list2, key = lambda item: sort_order.get(item["exchange"], float('inf'))) - return items[0]["price"] if len(items) > 0 else None diff --git a/fastlane_bot/modes/base_pairwise.py b/fastlane_bot/modes/base_pairwise.py index 91b5b5d4e..fa3fc93ac 100644 --- a/fastlane_bot/modes/base_pairwise.py +++ b/fastlane_bot/modes/base_pairwise.py @@ -29,7 +29,7 @@ def find_arbitrage(self) -> Dict[List[Any], List[Any]]: try: container = CPCContainer(curve_combos) optimizer = PairOptimizer(container) - params = get_params(container, dst_token, src_token) + params = self.get_params(container, [dst_token], src_token) optimization = optimizer.optimize(src_token, params=params) trade_instructions_dic = optimization.trade_instructions(optimizer.TIF_DICTS) trade_instructions_df = optimization.trade_instructions(optimizer.TIF_DFAGGR) @@ -45,7 +45,3 @@ def find_arbitrage(self) -> Dict[List[Any], List[Any]]: arb_opps.append({"profit": profit, "src_token": src_token, "trade_instructions_dic": trade_instructions_dic}) return {"combos": combos, "arb_opps": sorted(arb_opps, key=lambda arb_opp: arb_opp["profit"], reverse=True)} - -def get_params(container, dst_token, src_token): - pstart = {dst_token: container.bypairs(f"{dst_token}/{src_token}").curves[0].p} - return {"pstart": pstart} diff --git a/fastlane_bot/modes/base_triangle.py b/fastlane_bot/modes/base_triangle.py index 86d168bd1..3ad38d021 100644 --- a/fastlane_bot/modes/base_triangle.py +++ b/fastlane_bot/modes/base_triangle.py @@ -22,7 +22,7 @@ def find_arbitrage(self) -> Dict[List[Any], List[Any]]: try: container = CPCContainer(miniverse) optimizer = MargPOptimizer(container) - params = get_params(container, src_token) + params = self.get_params(container, container.tokens(), src_token) optimization = optimizer.optimize(src_token, params=params) trade_instructions_dic = optimization.trade_instructions(optimizer.TIF_DICTS) trade_instructions_df = optimization.trade_instructions(optimizer.TIF_DFAGGR) @@ -38,18 +38,3 @@ def find_arbitrage(self) -> Dict[List[Any], List[Any]]: arb_opps.append({"profit": profit, "src_token": src_token, "trade_instructions_dic": trade_instructions_dic}) return {"combos": combos, "arb_opps": sorted(arb_opps, key=lambda arb_opp: arb_opp["profit"], reverse=True)} - -def get_params(container, src_token): - pstart = {src_token: 1} - for dst_token in container.tokens(): - if dst_token != src_token: - curves = container.bytknx(dst_token).bytkny(src_token).curves - if len(curves) > 0: - pstart[dst_token] = curves[0].p - else: - curves = container.bytknx(src_token).bytkny(dst_token).curves - if len(curves) > 0: - pstart[dst_token] = 1 / curves[0].p - else: - return None - return {"pstart": pstart}