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}