diff --git a/fastlane_bot/bot.py b/fastlane_bot/bot.py index 5c62b5eaf..ccc8179a0 100644 --- a/fastlane_bot/bot.py +++ b/fastlane_bot/bot.py @@ -75,7 +75,6 @@ from .events.interface import QueryInterface from .modes.pairwise_multi import FindArbitrageMultiPairwise from .modes.pairwise_multi_all import FindArbitrageMultiPairwiseAll -from .modes.pairwise_multi_bal import FindArbitrageMultiPairwiseBalancer from .modes.pairwise_multi_pol import FindArbitrageMultiPairwisePol from .modes.pairwise_single import FindArbitrageSinglePairwise from .modes.triangle_multi import ArbitrageFinderTriangleMulti @@ -427,8 +426,6 @@ def _get_arb_finder(arb_mode: str) -> Callable: return ArbitrageFinderTriangleBancor3TwoHop elif arb_mode in {"multi_pairwise_pol"}: return FindArbitrageMultiPairwisePol - elif arb_mode in {"multi_pairwise_bal"}: - return FindArbitrageMultiPairwiseBalancer elif arb_mode in {"multi_pairwise_all"}: return FindArbitrageMultiPairwiseAll diff --git a/fastlane_bot/modes/pairwise_multi_all.py b/fastlane_bot/modes/pairwise_multi_all.py index 2cd213fac..ca48cf032 100644 --- a/fastlane_bot/modes/pairwise_multi_all.py +++ b/fastlane_bot/modes/pairwise_multi_all.py @@ -31,7 +31,8 @@ def find_arbitrage(self, candidates: List[Any] = None, ops: Tuple = None, best_p candidates = [] all_tokens, combos = self.get_combos(self.CCm, self.flashloan_tokens) - + if self.result == self.AO_TOKENS: + return all_tokens, combos #print(f"combos = {combos}") candidates = [] diff --git a/fastlane_bot/modes/pairwise_multi_bal.py b/fastlane_bot/modes/pairwise_multi_bal.py deleted file mode 100644 index caa64b02b..000000000 --- a/fastlane_bot/modes/pairwise_multi_bal.py +++ /dev/null @@ -1,211 +0,0 @@ -# coding=utf-8 -""" -Multi-pairwise arbitrage finder mode - -(c) Copyright Bprotocol foundation 2023. -Licensed under MIT -""" -import itertools -from typing import List, Any, Tuple, Union, Hashable - -import pandas as pd - -from fastlane_bot.modes.base_pairwise import ArbitrageFinderPairwiseBase -from fastlane_bot.tools.cpc import CPCContainer -from fastlane_bot.tools.optimizer import MargPOptimizer, PairOptimizer - - -class FindArbitrageMultiPairwiseBalancer(ArbitrageFinderPairwiseBase): - """ - Multi-pairwise arbitrage finder mode. - """ - - arb_mode = "multi_pairwise_bal" - - def find_arbitrage(self, candidates: List[Any] = None, ops: Tuple = None, best_profit: float = 0, profit_src: float = 0) -> Union[List, Tuple]: - """ - see base.py - """ - if self.base_exchange != "carbon_v1": - raise ValueError("base_exchange must be carbon_v1 for `multi` mode") - - if candidates is None: - candidates = [] - - combos = self.get_balancer_combos(self.CCm, self.flashloan_tokens) - - candidates = [] - self.ConfigObj.logger.debug( - f"\n ************ combos: {len(combos)} ************\n" - ) - for tkn0, tkn1 in combos: - r = None - CC = self.CCm.bypairs(f"{tkn0}/{tkn1}") - if len(CC) < 2: - continue - carbon_curves = [x for x in CC.curves if x.params.exchange == "carbon_v1"] - not_bal_curves = [ - x for x in CC.curves if x.params.exchange != "balancer" - ] - - bal_curves = [x for x in CC.curves if x.params.exchange == "balancer"] - curve_combos = [[bal_curve] + [curve] for curve in not_bal_curves for bal_curve in bal_curves] - curve_combos += [[bal_curve] + carbon_curves for bal_curve in bal_curves] - - for curve_combo in curve_combos: - src_token = tkn1 - if len(curve_combo) < 2: - continue - - ( - O, - profit_src, - r, - trade_instructions_df, - ) = self.run_main_flow(curves=curve_combo, src_token=src_token, tkn0=tkn0, tkn1=tkn1) - - - non_carbon_cids = [ - curve.cid - for curve in curve_combo - if curve.params.get("exchange") != "carbon_v1" - ] - carbon_cids = [ - curve.cid - for curve in curve_combo - if curve.params.get("exchange") == "carbon_v1" - ] - - if len(carbon_cids) > 0: - if non_carbon_cids[0] in trade_instructions_df.index and carbon_cids[0] in trade_instructions_df.index: - non_carbon_row = trade_instructions_df.loc[non_carbon_cids[0]] - tkn0_into_carbon = non_carbon_row[0] < 0 - wrong_direction_cids = self.get_wrong_direction_cids( - tkn0_into_carbon, trade_instructions_df - ) - if len(wrong_direction_cids) > 0: - filtered_curves = self.process_wrong_direction_pools( - curve_combo=curve_combo, wrong_direction_cids=wrong_direction_cids - ) - if len(filtered_curves) < 2: - continue - ( - O, - profit_src, - r, - trade_instructions_df, - ) = self.run_main_flow(curves=filtered_curves, src_token=src_token, tkn0=tkn0, tkn1=tkn1) - - trade_instructions_dic = r.trade_instructions(O.TIF_DICTS) - trade_instructions = r.trade_instructions() - if trade_instructions_dic is None: - continue - if len(trade_instructions_dic) < 2: - continue - # Get the cids - cids = [ti["cid"] for ti in trade_instructions_dic] - - # Calculate the profit - profit = self.calculate_profit(src_token, profit_src, self.CCm, cids) - - if str(profit) == "nan": - self.ConfigObj.logger.debug("profit is nan, skipping") - continue - - # Handle candidates based on conditions - candidates += self.handle_candidates( - best_profit, - profit, - trade_instructions_df, - trade_instructions_dic, - src_token, - trade_instructions, - ) - - # Find the best operations - best_profit, ops = self.find_best_operations( - best_profit, - ops, - profit, - trade_instructions_df, - trade_instructions_dic, - src_token, - trade_instructions, - ) - - return candidates if self.result == self.AO_CANDIDATES else ops - - @staticmethod - def get_wrong_direction_cids( - tkn0_into_carbon: bool, trade_instructions_df: pd.DataFrame - ) -> List[Hashable]: - """ - Get the cids of the wrong direction curves - - Parameters - ---------- - tkn0_into_carbon : bool - True if tkn0 is being converted into carbon, False otherwise - trade_instructions_df : pd.DataFrame - The trade instructions dataframe - - Returns - ------- - List[str] - The cids of the wrong direction curves - """ - return [ - idx - for idx, row in trade_instructions_df.iterrows() - if ( - (tkn0_into_carbon and row.iloc[0] < 0) - or (not tkn0_into_carbon and row.iloc[0] > 0) - ) - and ("-0" in idx or "-1" in idx) - ] - - @staticmethod - def run_main_flow( - curves: List[Any], src_token: str, tkn0: str, tkn1: str - ) -> Tuple[Any, float, Any, pd.DataFrame]: - """ - Run main flow to find arbitrage. - """ - CC_cc = CPCContainer(curves) - O = PairOptimizer(CC_cc) - pstart = { - tkn0: CC_cc.bypairs(f"{tkn0}/{tkn1}")[0].p - } # this intentionally selects the non_carbon curve - r = O.optimize(src_token, params=dict(pstart=pstart)) - profit_src = -r.result - trade_instructions_df = r.trade_instructions(O.TIF_DFAGGR) - return O, profit_src, r, trade_instructions_df - - @staticmethod - def process_wrong_direction_pools( - curve_combo: List[Any], wrong_direction_cids: List[Hashable] - ) -> [str]: - """ - Process curves with wrong direction pools. - """ - new_curves = [ - curve for curve in curve_combo if curve.cid not in wrong_direction_cids - ] - return new_curves - - @staticmethod - def get_balancer_combos(CCm, flashloan_tokens): - balancer_curves = CCm.byparams(exchange="balancer").curves - bal_tkns_raw = [curve.tkny for curve in balancer_curves] - bal_tkns_raw += [curve.tknx for curve in balancer_curves] - bal_tkns_raw = list(set(bal_tkns_raw)) - - if "WETH-6Cc2" in flashloan_tokens: - flashloan_tokens = ["WETH-6Cc2"] - else: - flashloan_tokens = [flashloan_tokens[0]] - combos = [(tkn0, tkn1) for tkn0, tkn1 in itertools.product(bal_tkns_raw, flashloan_tokens) if tkn0 != tkn1] - # note that the pair is tkn0/tkn1, ie tkn1 is the quote token - - return combos - diff --git a/fastlane_bot/modes/pairwise_multi_pol.py b/fastlane_bot/modes/pairwise_multi_pol.py index 25b3532e6..c74c4e0fe 100644 --- a/fastlane_bot/modes/pairwise_multi_pol.py +++ b/fastlane_bot/modes/pairwise_multi_pol.py @@ -28,6 +28,8 @@ def find_arbitrage(self, candidates: List[Any] = None, ops: Tuple = None, best_p """ all_tokens, combos = self.get_combos_pol(self.CCm, self.flashloan_tokens) + if self.result == self.AO_TOKENS: + return all_tokens, combos candidates = [] self.ConfigObj.logger.debug( @@ -191,7 +193,7 @@ def get_combos_pol(self, """ bancor_pol_tkns = CCm.byparams(exchange="bancor_pol").tokens() - bancor_pol_tkns = [tkn for tkn in bancor_pol_tkns if tkn not in [T.ETH, T.WETH]] + bancor_pol_tkns = set([tkn for tkn in bancor_pol_tkns if tkn not in [T.ETH, T.WETH]]) combos = [ (tkn0, tkn1) diff --git a/main.py b/main.py index a0c3a9cb3..8ae754cbd 100644 --- a/main.py +++ b/main.py @@ -95,7 +95,6 @@ "multi_triangle", "b3_two_hop", "multi_pairwise_pol", - "multi_pairwise_bal", "multi_pairwise_all", ] ), diff --git a/resources/NBTest/NBTest_039_TestMultiMode.ipynb b/resources/NBTest/NBTest_039_TestMultiMode.ipynb index 56079daab..3f7230cc4 100644 --- a/resources/NBTest/NBTest_039_TestMultiMode.ipynb +++ b/resources/NBTest/NBTest_039_TestMultiMode.ipynb @@ -89,13 +89,13 @@ "name": "stderr", "output_type": "stream", "text": [ - "2023-12-18 13:28:01,226 [fastlane:INFO] - \n", - "2023-12-18 13:28:01,226 [fastlane:INFO] - **********************************************\n", - "2023-12-18 13:28:01,227 [fastlane:INFO] - The logging path is set to: logs/20231218-132801\\bot.log\n", - "2023-12-18 13:28:01,227 [fastlane:INFO] - **********************************************\n", - "2023-12-18 13:28:01,228 [fastlane:INFO] - \n", - "2023-12-18 13:28:05,501 [fastlane:INFO] - Time taken to add initial pools: 0.1143178939819336\n", - "2023-12-18 13:28:05,504 [fastlane:INFO] - Initializing the bot...\n" + "2024-01-08 11:45:38,793 [fastlane:INFO] - \n", + "2024-01-08 11:45:38,794 [fastlane:INFO] - **********************************************\n", + "2024-01-08 11:45:38,794 [fastlane:INFO] - The logging path is set to: logs/20240108-114538\\bot.log\n", + "2024-01-08 11:45:38,795 [fastlane:INFO] - **********************************************\n", + "2024-01-08 11:45:38,795 [fastlane:INFO] - \n", + "2024-01-08 11:45:42,596 [fastlane:INFO] - Time taken to add initial pools: 0.1060800552368164\n", + "2024-01-08 11:45:42,599 [fastlane:INFO] - Initializing the bot...\n" ] } ], @@ -278,10 +278,10 @@ " )\n", "all_tokens, combos = finder2.find_arbitrage()\n", "\n", - "assert type(all_tokens) == set, f\"[TestMultiMode] all_tokens is wrong data type. Expected set, found: {type(all_tokens)}\"\n", - "assert type(combos) == list, f\"[TestMultiMode] combos is wrong data type. Expected list, found: {type(combos)}\"\n", - "assert len(all_tokens) > 100, f\"[TestMultiMode] Using wrong dataset, expected at least 100 tokens, found {len(all_tokens)}\"\n", - "assert len(combos) > 1000, f\"[TestMultiMode] Using wrong dataset, expected at least 100 combos, found {len(combos)}\"" + "assert type(all_tokens) == set, f\"[NBTest 039 TestMultiMode] all_tokens is wrong data type. Expected set, found: {type(all_tokens)}\"\n", + "assert type(combos) == list, f\"[NBTest 039 TestMultiMode] combos is wrong data type. Expected list, found: {type(combos)}\"\n", + "assert len(all_tokens) >= 236, f\"[NBTest 039 TestMultiMode] Using wrong dataset, expected at least 236 tokens, found {len(all_tokens)}\"\n", + "assert len(combos) >= 1410, f\"[NBTest 039 TestMultiMode] Using wrong dataset, expected at least 1410 combos, found {len(combos)}\"" ] }, { @@ -294,7 +294,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "id": "48e2f5a1", "metadata": { "ExecuteTime": { @@ -304,39 +304,7 @@ }, "outputs": [], "source": [ - "arb_finder = bot._get_arb_finder(\"multi\")\n", - "finder = arb_finder(\n", - " flashloan_tokens=flashloan_tokens,\n", - " CCm=CCm,\n", - " mode=\"bothin\",\n", - " result=bot.AO_CANDIDATES,\n", - " ConfigObj=bot.ConfigObj,\n", - " )\n", - "r = finder.find_arbitrage()\n", - "assert len(r) >= 25, f\"[TestMultiMode] Expected at least 25 arbs, found {len(r)}\"\n" - ] - }, - { - "cell_type": "markdown", - "id": "31ab38a8", - "metadata": {}, - "source": [ - "## Test_Multiple_Curves_Used" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "4310f546", - "metadata": { - "ExecuteTime": { - "end_time": "2023-09-18T18:15:47.354305Z", - "start_time": "2023-09-18T18:15:46.874096Z" - } - }, - "outputs": [], - "source": [ - "arb_finder = bot._get_arb_finder(\"multi\")\n", + "arb_finder = bot._get_arb_finder(\"multi_pairwise_pol\")\n", "finder = arb_finder(\n", " flashloan_tokens=flashloan_tokens,\n", " CCm=CCm,\n", @@ -344,9 +312,11 @@ " result=bot.AO_CANDIDATES,\n", " ConfigObj=bot.ConfigObj,\n", " )\n", + "\n", "r = finder.find_arbitrage()\n", - "multi_carbon_count = 0\n", "\n", + "multi_carbon_count = 0\n", + "carbon_wrong_direction_count = 0\n", "for arb in r:\n", " (\n", " best_profit,\n", @@ -357,49 +327,18 @@ " ) = arb\n", " if len(best_trade_instructions_dic) > 2:\n", " multi_carbon_count += 1\n", + " carbon_tkn_in = None\n", + " for trade in best_trade_instructions_dic:\n", + " if \"-\" in trade[\"cid\"]:\n", + " if carbon_tkn_in is None:\n", + " carbon_tkn_in = trade[\"tknin\"]\n", + " else:\n", + " if trade[\"tknin\"] not in carbon_tkn_in:\n", + " carbon_wrong_direction_count += 1\n", "\n", - "assert multi_carbon_count > 0, f\"[TestMultiMode] Not finding arbs with multiple Carbon curves.\"" - ] - }, - { - "cell_type": "markdown", - "id": "76ef76dc", - "metadata": {}, - "source": [ - "## Test_Single_Direction_Carbon_Curves" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "1b8a8538", - "metadata": { - "ExecuteTime": { - "end_time": "2023-09-18T18:15:47.370598Z", - "start_time": "2023-09-18T18:15:47.359023Z" - } - }, - "outputs": [], - "source": [ - "arb_finder = bot._get_arb_finder(\"multi\")\n", - "finder = arb_finder(\n", - " flashloan_tokens=flashloan_tokens,\n", - " CCm=CCm,\n", - " mode=\"bothin\",\n", - " result=bot.AO_CANDIDATES,\n", - " ConfigObj=bot.ConfigObj,\n", - " )\n", - "src_token=\"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\" \n", - "wrong_direction_cids = ['4083388403051261561560495289181218537493-0', '4083388403051261561560495289181218537579-0', '4083388403051261561560495289181218537610-0', '4083388403051261561560495289181218537629-0', '4083388403051261561560495289181218537639-0', '4083388403051261561560495289181218537755-0']\n", - "curves_before = [ConstantProductCurve(k=2290523503.4460173, x=273.1073125047371, x_act=0.07743961144774403, y_act=1814.6001096442342, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='0x8d7ac7e77704f3ac75534d5500159a7a4b7e6e23dbdca7d9a8085bdea0348d0c', fee=0.0005, descr='uniswap_v3 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 500', constr='pkpp', params={'exchange': 'uniswap_v3', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17675876, 'L': 47859.413948}), ConstantProductCurve(k=3675185.41145277, x=11.059038979187497, x_act=0, y_act=1385.267061, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537493-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 1385.267061, 'yint': 1385.267061, 'A': 0.722593217276426, 'B': 172.62676501631972, 'pa': 30049.999999999647, 'pb': 29799.999999999665}), ConstantProductCurve(k=29672.782767383174, x=1.0315213950985431, x_act=0, y_act=3651.804716, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537579-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 3651.804716, 'yint': 3651.804716, 'A': 21.199636119827687, 'B': 145.79437574886072, 'pa': 27886.999999999643, 'pb': 21255.999999999985}), ConstantProductCurve(k=6.863635116394053e+16, x=1525337.9097739116, x_act=0, y_act=4499.746836, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537610-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 4499.746836, 'yint': 4499.746836, 'A': 0, 'B': 171.7556317853946, 'pa': 29499.99999999976, 'pb': 29499.99999999976}), ConstantProductCurve(k=143046.70577155304, x=2.1824671097293846, x_act=0, y_act=5742.51191, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537629-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 5742.51191, 'yint': 6413.595264, 'A': 16.957530991696217, 'B': 158.11388300841884, 'pa': 30649.99999999968, 'pb': 24999.99999999996}), ConstantProductCurve(k=5459975.623181331, x=437148.88403306017, x_act=0, y_act=0.50315999, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537629-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.50315999, 'yint': 0.50315999, 'A': 0.0002153330778227767, 'B': 0.005129891760425664, 'pa': 2.8571428571428076e-05, 'pb': 2.631578947368312e-05}), ConstantProductCurve(k=443607.9519434853, x=3.85826034424969, x_act=0, y_act=9876.976514, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537639-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 9876.976514, 'yint': 9876.976514, 'A': 14.829426635724872, 'B': 157.79733838059485, 'pa': 29799.999999999665, 'pb': 24899.999999999953}), ConstantProductCurve(k=5324.625267368582, x=12680.839210183807, x_act=0, y_act=0.01198047, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537639-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.01198047, 'yint': 0.01198047, 'A': 0.00016418343273514376, 'B': 0.0055901699437491455, 'pa': 3.311258278145614e-05, 'pb': 3.124999999999633e-05}), ConstantProductCurve(k=3316749913763783.5, x=331674.9583747572, x_act=0, y_act=1000.0, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537755-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 1000.0, 'yint': 1000.0, 'A': 0, 'B': 173.63754485997586, 'pa': 30149.999999999825, 'pb': 30149.999999999825})]\n", - "curves_expected_after = [ConstantProductCurve(k=2290523503.4460173, x=273.1073125047371, x_act=0.07743961144774403, y_act=1814.6001096442342, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='0x8d7ac7e77704f3ac75534d5500159a7a4b7e6e23dbdca7d9a8085bdea0348d0c', fee=0.0005, descr='uniswap_v3 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 500', constr='pkpp', params={'exchange': 'uniswap_v3', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17675876, 'L': 47859.413948}), ConstantProductCurve(k=5459975.623181331, x=437148.88403306017, x_act=0, y_act=0.50315999, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537629-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.50315999, 'yint': 0.50315999, 'A': 0.0002153330778227767, 'B': 0.005129891760425664, 'pa': 2.8571428571428076e-05, 'pb': 2.631578947368312e-05}), ConstantProductCurve(k=5324.625267368582, x=12680.839210183807, x_act=0, y_act=0.01198047, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537639-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.01198047, 'yint': 0.01198047, 'A': 0.00016418343273514376, 'B': 0.0055901699437491455, 'pa': 3.311258278145614e-05, 'pb': 3.124999999999633e-05})]\n", - "test_process_wrong_direction_pools = finder.process_wrong_direction_pools(curve_combo=curves_before, wrong_direction_cids=wrong_direction_cids)\n", - "O, profit_src, r, trade_instructions_df = finder.run_main_flow(curves=curves_expected_after, src_token=\"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\", tkn0=\"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\", tkn1=\"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\")\n", - "\n", - "assert len(curves_before) - len(wrong_direction_cids) == len(test_process_wrong_direction_pools), f\"[TestMultiMode] Wrong direction CIDs not removed correctly, started with {len(curves_before)}, removing {len(wrong_direction_cids)}, expected {len(curves_before) - len(wrong_direction_cids)} got {len(test_process_wrong_direction_pools)}\"\n", - "for curve in test_process_wrong_direction_pools:\n", - " assert curve.cid not in wrong_direction_cids, f\"[TestMultiMode] Failed to remove curve {curve.cid} from list of wrong direction pools\"\n", - "assert iseq(profit_src, 2.905623487869935e-05)" + "assert len(r) >= 36, f\"[NBTest 039 TestMultiMode] Expected at least 27 arbs, found {len(r)}\"\n", + "assert multi_carbon_count > 0, f\"[NBTest 039 TestMultiMode] Not finding arbs with multiple Carbon curves.\"\n", + "assert carbon_wrong_direction_count == 0, f\"[NBTest 039 TestMultiMode] Expected all Carbon curves to have the same tkn in and tkn out. Mixing is currently not supported.\"" ] }, { diff --git a/resources/NBTest/NBTest_039_TestMultiMode.py b/resources/NBTest/NBTest_039_TestMultiMode.py index 0f0976667..1db4e0a81 100644 --- a/resources/NBTest/NBTest_039_TestMultiMode.py +++ b/resources/NBTest/NBTest_039_TestMultiMode.py @@ -169,30 +169,16 @@ def init_bot(mgr: Manager) -> CarbonBot: ) all_tokens, combos = finder2.find_arbitrage() -assert type(all_tokens) == set, f"[TestMultiMode] all_tokens is wrong data type. Expected set, found: {type(all_tokens)}" -assert type(combos) == list, f"[TestMultiMode] combos is wrong data type. Expected list, found: {type(combos)}" -assert len(all_tokens) > 100, f"[TestMultiMode] Using wrong dataset, expected at least 100 tokens, found {len(all_tokens)}" -assert len(combos) > 1000, f"[TestMultiMode] Using wrong dataset, expected at least 100 combos, found {len(combos)}" +assert type(all_tokens) == set, f"[NBTest 039 TestMultiMode] all_tokens is wrong data type. Expected set, found: {type(all_tokens)}" +assert type(combos) == list, f"[NBTest 039 TestMultiMode] combos is wrong data type. Expected list, found: {type(combos)}" +assert len(all_tokens) >= 236, f"[NBTest 039 TestMultiMode] Using wrong dataset, expected at least 236 tokens, found {len(all_tokens)}" +assert len(combos) >= 1410, f"[NBTest 039 TestMultiMode] Using wrong dataset, expected at least 1410 combos, found {len(combos)}" # - # ## Test_Expected_Output -arb_finder = bot._get_arb_finder("multi") -finder = arb_finder( - flashloan_tokens=flashloan_tokens, - CCm=CCm, - mode="bothin", - result=bot.AO_CANDIDATES, - ConfigObj=bot.ConfigObj, - ) -r = finder.find_arbitrage() -assert len(r) >= 25, f"[TestMultiMode] Expected at least 25 arbs, found {len(r)}" - - -# ## Test_Multiple_Curves_Used - # + -arb_finder = bot._get_arb_finder("multi") +arb_finder = bot._get_arb_finder("multi_pairwise_pol") finder = arb_finder( flashloan_tokens=flashloan_tokens, CCm=CCm, @@ -200,9 +186,11 @@ def init_bot(mgr: Manager) -> CarbonBot: result=bot.AO_CANDIDATES, ConfigObj=bot.ConfigObj, ) + r = finder.find_arbitrage() -multi_carbon_count = 0 +multi_carbon_count = 0 +carbon_wrong_direction_count = 0 for arb in r: ( best_profit, @@ -213,32 +201,18 @@ def init_bot(mgr: Manager) -> CarbonBot: ) = arb if len(best_trade_instructions_dic) > 2: multi_carbon_count += 1 - -assert multi_carbon_count > 0, f"[TestMultiMode] Not finding arbs with multiple Carbon curves." -# - - -# ## Test_Single_Direction_Carbon_Curves - -# + -arb_finder = bot._get_arb_finder("multi") -finder = arb_finder( - flashloan_tokens=flashloan_tokens, - CCm=CCm, - mode="bothin", - result=bot.AO_CANDIDATES, - ConfigObj=bot.ConfigObj, - ) -src_token="0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599" -wrong_direction_cids = ['4083388403051261561560495289181218537493-0', '4083388403051261561560495289181218537579-0', '4083388403051261561560495289181218537610-0', '4083388403051261561560495289181218537629-0', '4083388403051261561560495289181218537639-0', '4083388403051261561560495289181218537755-0'] -curves_before = [ConstantProductCurve(k=2290523503.4460173, x=273.1073125047371, x_act=0.07743961144774403, y_act=1814.6001096442342, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='0x8d7ac7e77704f3ac75534d5500159a7a4b7e6e23dbdca7d9a8085bdea0348d0c', fee=0.0005, descr='uniswap_v3 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 500', constr='pkpp', params={'exchange': 'uniswap_v3', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17675876, 'L': 47859.413948}), ConstantProductCurve(k=3675185.41145277, x=11.059038979187497, x_act=0, y_act=1385.267061, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537493-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 1385.267061, 'yint': 1385.267061, 'A': 0.722593217276426, 'B': 172.62676501631972, 'pa': 30049.999999999647, 'pb': 29799.999999999665}), ConstantProductCurve(k=29672.782767383174, x=1.0315213950985431, x_act=0, y_act=3651.804716, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537579-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 3651.804716, 'yint': 3651.804716, 'A': 21.199636119827687, 'B': 145.79437574886072, 'pa': 27886.999999999643, 'pb': 21255.999999999985}), ConstantProductCurve(k=6.863635116394053e+16, x=1525337.9097739116, x_act=0, y_act=4499.746836, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537610-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 4499.746836, 'yint': 4499.746836, 'A': 0, 'B': 171.7556317853946, 'pa': 29499.99999999976, 'pb': 29499.99999999976}), ConstantProductCurve(k=143046.70577155304, x=2.1824671097293846, x_act=0, y_act=5742.51191, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537629-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 5742.51191, 'yint': 6413.595264, 'A': 16.957530991696217, 'B': 158.11388300841884, 'pa': 30649.99999999968, 'pb': 24999.99999999996}), ConstantProductCurve(k=5459975.623181331, x=437148.88403306017, x_act=0, y_act=0.50315999, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537629-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.50315999, 'yint': 0.50315999, 'A': 0.0002153330778227767, 'B': 0.005129891760425664, 'pa': 2.8571428571428076e-05, 'pb': 2.631578947368312e-05}), ConstantProductCurve(k=443607.9519434853, x=3.85826034424969, x_act=0, y_act=9876.976514, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537639-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 9876.976514, 'yint': 9876.976514, 'A': 14.829426635724872, 'B': 157.79733838059485, 'pa': 29799.999999999665, 'pb': 24899.999999999953}), ConstantProductCurve(k=5324.625267368582, x=12680.839210183807, x_act=0, y_act=0.01198047, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537639-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.01198047, 'yint': 0.01198047, 'A': 0.00016418343273514376, 'B': 0.0055901699437491455, 'pa': 3.311258278145614e-05, 'pb': 3.124999999999633e-05}), ConstantProductCurve(k=3316749913763783.5, x=331674.9583747572, x_act=0, y_act=1000.0, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='4083388403051261561560495289181218537755-0', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 1000.0, 'yint': 1000.0, 'A': 0, 'B': 173.63754485997586, 'pa': 30149.999999999825, 'pb': 30149.999999999825})] -curves_expected_after = [ConstantProductCurve(k=2290523503.4460173, x=273.1073125047371, x_act=0.07743961144774403, y_act=1814.6001096442342, pair='0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', cid='0x8d7ac7e77704f3ac75534d5500159a7a4b7e6e23dbdca7d9a8085bdea0348d0c', fee=0.0005, descr='uniswap_v3 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 500', constr='pkpp', params={'exchange': 'uniswap_v3', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17675876, 'L': 47859.413948}), ConstantProductCurve(k=5459975.623181331, x=437148.88403306017, x_act=0, y_act=0.50315999, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537629-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.50315999, 'yint': 0.50315999, 'A': 0.0002153330778227767, 'B': 0.005129891760425664, 'pa': 2.8571428571428076e-05, 'pb': 2.631578947368312e-05}), ConstantProductCurve(k=5324.625267368582, x=12680.839210183807, x_act=0, y_act=0.01198047, pair='0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', cid='4083388403051261561560495289181218537639-1', fee=0.002, descr='carbon_v1 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 0.002', constr='carb', params={'exchange': 'carbon_v1', 'tknx_dec': 8, 'tkny_dec': 6, 'tknx_addr': '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 'tkny_addr': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 'blocklud': 17674427, 'y': 0.01198047, 'yint': 0.01198047, 'A': 0.00016418343273514376, 'B': 0.0055901699437491455, 'pa': 3.311258278145614e-05, 'pb': 3.124999999999633e-05})] -test_process_wrong_direction_pools = finder.process_wrong_direction_pools(curve_combo=curves_before, wrong_direction_cids=wrong_direction_cids) -O, profit_src, r, trade_instructions_df = finder.run_main_flow(curves=curves_expected_after, src_token="0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", tkn0="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", tkn1="0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599") - -assert len(curves_before) - len(wrong_direction_cids) == len(test_process_wrong_direction_pools), f"[TestMultiMode] Wrong direction CIDs not removed correctly, started with {len(curves_before)}, removing {len(wrong_direction_cids)}, expected {len(curves_before) - len(wrong_direction_cids)} got {len(test_process_wrong_direction_pools)}" -for curve in test_process_wrong_direction_pools: - assert curve.cid not in wrong_direction_cids, f"[TestMultiMode] Failed to remove curve {curve.cid} from list of wrong direction pools" -assert iseq(profit_src, 2.905623487869935e-05) + carbon_tkn_in = None + for trade in best_trade_instructions_dic: + if "-" in trade["cid"]: + if carbon_tkn_in is None: + carbon_tkn_in = trade["tknin"] + else: + if trade["tknin"] not in carbon_tkn_in: + carbon_wrong_direction_count += 1 + +assert len(r) >= 36, f"[NBTest 039 TestMultiMode] Expected at least 27 arbs, found {len(r)}" +assert multi_carbon_count > 0, f"[NBTest 039 TestMultiMode] Not finding arbs with multiple Carbon curves." +assert carbon_wrong_direction_count == 0, f"[NBTest 039 TestMultiMode] Expected all Carbon curves to have the same tkn in and tkn out. Mixing is currently not supported." # - diff --git a/resources/NBTest/NBTest_040_TestSingleMode.ipynb b/resources/NBTest/NBTest_040_TestSingleMode.ipynb index 8605b2bdc..a3ce461ce 100644 --- a/resources/NBTest/NBTest_040_TestSingleMode.ipynb +++ b/resources/NBTest/NBTest_040_TestSingleMode.ipynb @@ -90,13 +90,13 @@ "name": "stderr", "output_type": "stream", "text": [ - "2023-12-18 13:28:56,680 [fastlane:INFO] - \n", - "2023-12-18 13:28:56,681 [fastlane:INFO] - **********************************************\n", - "2023-12-18 13:28:56,681 [fastlane:INFO] - The logging path is set to: logs/20231218-132856\\bot.log\n", - "2023-12-18 13:28:56,682 [fastlane:INFO] - **********************************************\n", - "2023-12-18 13:28:56,682 [fastlane:INFO] - \n", - "2023-12-18 13:29:00,238 [fastlane:INFO] - Time taken to add initial pools: 0.11491942405700684\n", - "2023-12-18 13:29:00,242 [fastlane:INFO] - Initializing the bot...\n" + "2024-01-08 11:47:18,864 [fastlane:INFO] - \n", + "2024-01-08 11:47:18,864 [fastlane:INFO] - **********************************************\n", + "2024-01-08 11:47:18,864 [fastlane:INFO] - The logging path is set to: logs/20240108-114718\\bot.log\n", + "2024-01-08 11:47:18,864 [fastlane:INFO] - **********************************************\n", + "2024-01-08 11:47:18,866 [fastlane:INFO] - \n", + "2024-01-08 11:47:22,339 [fastlane:INFO] - Time taken to add initial pools: 0.10255932807922363\n", + "2024-01-08 11:47:22,342 [fastlane:INFO] - Initializing the bot...\n" ] } ], @@ -313,67 +313,54 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 2/2 [00:00= 20, f\"[TestSingleMode] Expected at least 20 arbs, found {len(r)}\"\n", - "assert len(r) == len(run_full), f\"[TestSingleMode] Expected arbs from .find_arbitrage - {len(r)} - to match _run - {len(run_full)}\"" - ] - }, - { - "cell_type": "markdown", - "id": "d4c12c4b", - "metadata": {}, - "source": [ - "## Test_no_multi_carbon" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "c4f92d83", - "metadata": { - "ExecuteTime": { - "end_time": "2023-09-18T18:19:11.961703Z", - "start_time": "2023-09-18T18:18:56.190922Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ "100%|██████████| 2/2 [00:00 2:\n", " multi_carbon_count += 1\n", "\n", - "assert multi_carbon_count == 0, f\"[TestSingleMode] Expected arbs without multiple Carbon curves, but found {len(multi_carbon_count)}\"" + "assert multi_carbon_count == 0, f\"[TestSingleMode] Expected arbs without multiple Carbon curves, but found {len(multi_carbon_count)}\"\n", + "assert len(r) >= 20, f\"[TestSingleMode] Expected at least 20 arbs, found {len(r)}\"\n", + "assert len(r) == len(run_full), f\"[TestSingleMode] Expected arbs from .find_arbitrage - {len(r)} - to match _run - {len(run_full)}\"" ] }, { diff --git a/resources/NBTest/NBTest_040_TestSingleMode.py b/resources/NBTest/NBTest_040_TestSingleMode.py index 5864f438a..5e8e9ecfb 100644 --- a/resources/NBTest/NBTest_040_TestSingleMode.py +++ b/resources/NBTest/NBTest_040_TestSingleMode.py @@ -181,6 +181,7 @@ def init_bot(mgr: Manager) -> CarbonBot: # ### Test_Single_Arb_Finder_vs_run +# + run_full = bot._run(flashloan_tokens=flashloan_tokens, CCm=CCm, arb_mode=arb_mode, data_validator=False, result=bot.XS_ARBOPPS) arb_finder = bot._get_arb_finder("single") finder = arb_finder( @@ -191,21 +192,7 @@ def init_bot(mgr: Manager) -> CarbonBot: ConfigObj=bot.ConfigObj, ) r = finder.find_arbitrage() -assert len(r) >= 20, f"[TestSingleMode] Expected at least 20 arbs, found {len(r)}" -assert len(r) == len(run_full), f"[TestSingleMode] Expected arbs from .find_arbitrage - {len(r)} - to match _run - {len(run_full)}" - -# ## Test_no_multi_carbon -# + -arb_finder = bot._get_arb_finder("single") -finder = arb_finder( - flashloan_tokens=flashloan_tokens, - CCm=CCm, - mode="bothin", - result=bot.AO_CANDIDATES, - ConfigObj=bot.ConfigObj, - ) -r = finder.find_arbitrage() multi_carbon_count = 0 for arb in r: @@ -220,6 +207,8 @@ def init_bot(mgr: Manager) -> CarbonBot: multi_carbon_count += 1 assert multi_carbon_count == 0, f"[TestSingleMode] Expected arbs without multiple Carbon curves, but found {len(multi_carbon_count)}" +assert len(r) >= 20, f"[TestSingleMode] Expected at least 20 arbs, found {len(r)}" +assert len(r) == len(run_full), f"[TestSingleMode] Expected arbs from .find_arbitrage - {len(r)} - to match _run - {len(run_full)}" # - diff --git a/resources/NBTest/NBTest_063_TestBancorPOLMode.py b/resources/NBTest/NBTest_063_TestBancorPOLMode.py new file mode 100644 index 000000000..32c01d9ff --- /dev/null +++ b/resources/NBTest/NBTest_063_TestBancorPOLMode.py @@ -0,0 +1,214 @@ +# --- +# jupyter: +# jupytext: +# formats: ipynb,py:light +# text_representation: +# extension: .py +# format_name: light +# format_version: '1.5' +# jupytext_version: 1.14.5 +# kernelspec: +# display_name: Python 3 +# language: python +# name: python3 +# --- + +# coding=utf-8 +""" +This module contains the tests for the exchanges classes +""" +from fastlane_bot import Bot, Config +from fastlane_bot.bot import CarbonBot +from fastlane_bot.tools.cpc import ConstantProductCurve +from fastlane_bot.tools.cpc import ConstantProductCurve as CPC +from fastlane_bot.events.exchanges import UniswapV2, UniswapV3, CarbonV1, BancorV3 +from fastlane_bot.events.interface import QueryInterface +from fastlane_bot.helpers.poolandtokens import PoolAndTokens +from fastlane_bot.helpers import TradeInstruction, TxReceiptHandler, TxRouteHandler, TxSubmitHandler, TxHelpers, TxHelper +from fastlane_bot.events.managers.manager import Manager +from fastlane_bot.events.interface import QueryInterface +from joblib import Parallel, delayed +import pytest +import math +import json +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(CPC)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(Bot)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(UniswapV2)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(UniswapV3)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(CarbonV1)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(BancorV3)) +from fastlane_bot.testing import * +#plt.style.use('seaborn-dark') +plt.rcParams['figure.figsize'] = [12,6] +from fastlane_bot import __VERSION__ +require("3.0", __VERSION__) + +# # Multi POL Mode [NB063] + +# + +C = cfg = Config.new(config=Config.CONFIG_MAINNET) +cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN = 0.00001 +assert (C.NETWORK == C.NETWORK_MAINNET) +assert (C.PROVIDER == C.PROVIDER_ALCHEMY) +setup_bot = CarbonBot(ConfigObj=C) +pools = None +with open('fastlane_bot/data/tests/latest_pool_data_testing.json') as f: + pools = json.load(f) +pools = [pool for pool in pools] +pools[0] +static_pools = pools +state = pools +exchanges = list({ex['exchange_name'] for ex in state}) +db = QueryInterface(state=state, ConfigObj=C, exchanges=exchanges) +setup_bot.db = db + +static_pool_data_filename = "static_pool_data" + +static_pool_data = pd.read_csv(f"fastlane_bot/data/{static_pool_data_filename}.csv", low_memory=False) + +uniswap_v2_event_mappings = pd.read_csv("fastlane_bot/data/uniswap_v2_event_mappings.csv", low_memory=False) + +tokens = pd.read_csv("fastlane_bot/data/tokens.csv", low_memory=False) + +exchanges = "carbon_v1,bancor_v3,uniswap_v3,uniswap_v2,sushiswap_v2,bancor_pol" + +exchanges = exchanges.split(",") + + +alchemy_max_block_fetch = 20 +static_pool_data["cid"] = [ + cfg.w3.keccak(text=f"{row['descr']}").hex() + for index, row in static_pool_data.iterrows() + ] +# Filter out pools that are not in the supported exchanges +static_pool_data = [ + row for index, row in static_pool_data.iterrows() + if row["exchange_name"] in exchanges +] + +static_pool_data = pd.DataFrame(static_pool_data) +static_pool_data['exchange_name'].unique() +# Initialize data fetch manager +mgr = Manager( + web3=cfg.w3, + w3_async=cfg.w3_async, + cfg=cfg, + pool_data=static_pool_data.to_dict(orient="records"), + SUPPORTED_EXCHANGES=exchanges, + alchemy_max_block_fetch=alchemy_max_block_fetch, + uniswap_v2_event_mappings=uniswap_v2_event_mappings, + tokens=tokens.to_dict(orient="records"), +) + +# Add initial pools for each row in the static_pool_data +start_time = time.time() +Parallel(n_jobs=-1, backend="threading")( + delayed(mgr.add_pool_to_exchange)(row) for row in mgr.pool_data +) +cfg.logger.info(f"Time taken to add initial pools: {time.time() - start_time}") + +# check if any duplicate cid's exist in the pool data +mgr.deduplicate_pool_data() +cids = [pool["cid"] for pool in mgr.pool_data] +assert len(cids) == len(set(cids)), "duplicate cid's exist in the pool data" +def init_bot(mgr: Manager) -> CarbonBot: + """ + Initializes the bot. + + Parameters + ---------- + mgr : Manager + The manager object. + + Returns + ------- + CarbonBot + The bot object. + """ + mgr.cfg.logger.info("Initializing the bot...") + bot = CarbonBot(ConfigObj=mgr.cfg) + bot.db = db + bot.db.mgr = mgr + assert isinstance( + bot.db, QueryInterface + ), "QueryInterface not initialized correctly" + return bot +bot = init_bot(mgr) +# add data cleanup steps from main.py +bot.db.remove_unmapped_uniswap_v2_pools() +bot.db.remove_zero_liquidity_pools() +bot.db.remove_unsupported_exchanges() +tokens = bot.db.get_tokens() +ADDRDEC = {t.address: (t.address, int(t.decimals)) for t in tokens if not math.isnan(t.decimals)} +flashloan_tokens = bot.setup_flashloan_tokens(None) +CCm = bot.setup_CCm(None) +pools = db.get_pool_data_with_tokens() + +arb_mode = "multi_pairwise_pol" +# - + +# ## Test_MIN_PROFIT + +assert(cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN <= 0.0001), f"[NBTest 063 TestMultiPairwisePOLMode], default_min_profit_gas_token must be <= 0.02 for this Notebook to run, currently set to {cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN}" + +# ## Test_get_arb_finder + +arb_finder = bot._get_arb_finder("multi_pairwise_pol") +assert arb_finder.__name__ == "FindArbitrageMultiPairwisePol", f"[NBTest 063 TestMultiPairwisePOLMode] Expected arb_finder class name name = FindArbitrageMultiPairwisePol, found {arb_finder.__name__}" + +# ## Test_Combos_and_Tokens + +arb_finder = bot._get_arb_finder("multi_pairwise_pol") +finder2 = arb_finder( + flashloan_tokens=flashloan_tokens, + CCm=CCm, + mode="bothin", + result=bot.AO_TOKENS, + ConfigObj=bot.ConfigObj, + ) +all_tokens, combos = finder2.find_arbitrage() +assert type(all_tokens) == set, f"[NBTest 063 TestMultiPairwisePOLMode] all_tokens is wrong data type. Expected set, found: {type(all_tokens)}" +assert "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C" in all_tokens, f"[NBTest 063 TestMultiPairwisePOLMode] Expected BNT address in all_tokens: {(all_tokens)}" +assert type(combos) == list, f"[NBTest 063 TestMultiPairwisePOLMode] combos is wrong data type. Expected list, found: {type(combos)}" +assert ('0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C', '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2') in combos or ('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', '0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C') in combos, f"[NBTest 063 TestMultiPairwisePOLMode] Expected BNT/WETH or WETH/BNT in combos" +assert len(all_tokens) >= 73, f"[NBTest 063 TestMultiPairwisePOLMode] Using wrong dataset, expected at least 73 tokens, found {len(all_tokens)}" +assert len(combos) >= 146, f"[NBTest 063 TestMultiPairwisePOLMode] Using wrong dataset, expected at least 146 combos, found {len(combos)}" + +# ## Test_Expected_Output + +# + +arb_finder = bot._get_arb_finder("multi_pairwise_pol") +finder = arb_finder( + flashloan_tokens=flashloan_tokens, + CCm=CCm, + mode="bothin", + result=bot.AO_CANDIDATES, + ConfigObj=bot.ConfigObj, + ) + +r = finder.find_arbitrage() + +multi_carbon_count = 0 +carbon_wrong_direction_count = 0 +for arb in r: + ( + best_profit, + best_trade_instructions_df, + best_trade_instructions_dic, + best_src_token, + best_trade_instructions, + ) = arb + if len(best_trade_instructions_dic) > 2: + multi_carbon_count += 1 + carbon_tkn_in = None + for trade in best_trade_instructions_dic: + if "-" in trade["cid"]: + if carbon_tkn_in is None: + carbon_tkn_in = trade["tknin"] + else: + if trade["tknin"] not in carbon_tkn_in: + carbon_wrong_direction_count += 1 + +assert len(r) >= 36, f"[NBTest 063 TestMultiPairwisePOLMode] Expected at least 27 arbs, found {len(r)}" +assert multi_carbon_count > 0, f"[NBTest 063 TestMultiPairwisePOLMode] Not finding arbs with multiple Carbon curves." +assert carbon_wrong_direction_count == 0, f"[NBTest 063 TestMultiPairwisePOLMode Mode] Expected all Carbon curves to have the same tkn in and tkn out. Mixing is currently not supported." diff --git a/resources/NBTest/NBTest_064_TestMultiAllMode.py b/resources/NBTest/NBTest_064_TestMultiAllMode.py new file mode 100644 index 000000000..9a598f34a --- /dev/null +++ b/resources/NBTest/NBTest_064_TestMultiAllMode.py @@ -0,0 +1,219 @@ +# --- +# jupyter: +# jupytext: +# formats: ipynb,py:light +# text_representation: +# extension: .py +# format_name: light +# format_version: '1.5' +# jupytext_version: 1.14.5 +# kernelspec: +# display_name: Python 3 +# language: python +# name: python3 +# --- + +# coding=utf-8 +""" +This module contains the tests for the exchanges classes +""" +from fastlane_bot import Bot, Config +from fastlane_bot.bot import CarbonBot +from fastlane_bot.tools.cpc import ConstantProductCurve +from fastlane_bot.tools.cpc import ConstantProductCurve as CPC +from fastlane_bot.events.exchanges import UniswapV2, UniswapV3, CarbonV1, BancorV3 +from fastlane_bot.events.interface import QueryInterface +from fastlane_bot.helpers.poolandtokens import PoolAndTokens +from fastlane_bot.helpers import TradeInstruction, TxReceiptHandler, TxRouteHandler, TxSubmitHandler, TxHelpers, TxHelper +from fastlane_bot.events.managers.manager import Manager +from fastlane_bot.events.interface import QueryInterface +from joblib import Parallel, delayed +import pytest +import math +import json +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(CPC)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(Bot)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(UniswapV2)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(UniswapV3)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(CarbonV1)) +print("{0.__name__} v{0.__VERSION__} ({0.__DATE__})".format(BancorV3)) +from fastlane_bot.testing import * +#plt.style.use('seaborn-dark') +plt.rcParams['figure.figsize'] = [12,6] +from fastlane_bot import __VERSION__ +require("3.0", __VERSION__) + +# # Multi Pairwise All Mode [NB064] + +# + +C = cfg = Config.new(config=Config.CONFIG_MAINNET) +cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN = 0.00001 +assert (C.NETWORK == C.NETWORK_MAINNET) +assert (C.PROVIDER == C.PROVIDER_ALCHEMY) +setup_bot = CarbonBot(ConfigObj=C) +pools = None +with open('fastlane_bot/data/tests/latest_pool_data_testing.json') as f: + pools = json.load(f) +pools = [pool for pool in pools] +pools[0] +static_pools = pools +state = pools +exchanges = list({ex['exchange_name'] for ex in state}) +db = QueryInterface(state=state, ConfigObj=C, exchanges=exchanges) +setup_bot.db = db + +static_pool_data_filename = "static_pool_data" + +static_pool_data = pd.read_csv(f"fastlane_bot/data/{static_pool_data_filename}.csv", low_memory=False) + +uniswap_v2_event_mappings = pd.read_csv("fastlane_bot/data/uniswap_v2_event_mappings.csv", low_memory=False) + +tokens = pd.read_csv("fastlane_bot/data/tokens.csv", low_memory=False) + +exchanges = "carbon_v1,bancor_v3,uniswap_v3,uniswap_v2,sushiswap_v2" + +exchanges = exchanges.split(",") + + +alchemy_max_block_fetch = 20 +static_pool_data["cid"] = [ + cfg.w3.keccak(text=f"{row['descr']}").hex() + for index, row in static_pool_data.iterrows() + ] +# Filter out pools that are not in the supported exchanges +static_pool_data = [ + row for index, row in static_pool_data.iterrows() + if row["exchange_name"] in exchanges +] + +static_pool_data = pd.DataFrame(static_pool_data) +static_pool_data['exchange_name'].unique() +# Initialize data fetch manager +mgr = Manager( + web3=cfg.w3, + w3_async=cfg.w3_async, + cfg=cfg, + pool_data=static_pool_data.to_dict(orient="records"), + SUPPORTED_EXCHANGES=exchanges, + alchemy_max_block_fetch=alchemy_max_block_fetch, + uniswap_v2_event_mappings=uniswap_v2_event_mappings, + tokens=tokens.to_dict(orient="records"), +) + +# Add initial pools for each row in the static_pool_data +start_time = time.time() +Parallel(n_jobs=-1, backend="threading")( + delayed(mgr.add_pool_to_exchange)(row) for row in mgr.pool_data +) +cfg.logger.info(f"Time taken to add initial pools: {time.time() - start_time}") + +# check if any duplicate cid's exist in the pool data +mgr.deduplicate_pool_data() +cids = [pool["cid"] for pool in mgr.pool_data] +assert len(cids) == len(set(cids)), "duplicate cid's exist in the pool data" +def init_bot(mgr: Manager) -> CarbonBot: + """ + Initializes the bot. + + Parameters + ---------- + mgr : Manager + The manager object. + + Returns + ------- + CarbonBot + The bot object. + """ + mgr.cfg.logger.info("Initializing the bot...") + bot = CarbonBot(ConfigObj=mgr.cfg) + bot.db = db + bot.db.mgr = mgr + assert isinstance( + bot.db, QueryInterface + ), "QueryInterface not initialized correctly" + return bot +bot = init_bot(mgr) +# add data cleanup steps from main.py +bot.db.remove_unmapped_uniswap_v2_pools() +bot.db.remove_zero_liquidity_pools() +bot.db.remove_unsupported_exchanges() +tokens = bot.db.get_tokens() +ADDRDEC = {t.address: (t.address, int(t.decimals)) for t in tokens if not math.isnan(t.decimals)} +flashloan_tokens = bot.setup_flashloan_tokens(None) +CCm = bot.setup_CCm(None) +pools = db.get_pool_data_with_tokens() + +arb_mode = "multi_pairwise_all" +# - + +# ## Test_MIN_PROFIT + +assert(cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN <= 0.0001), f"[NBTest64 TestMultiPairwiseAll Mode], default_min_profit_gas_token must be <= 0.02 for this Notebook to run, currently set to {cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN}" + +# ## Test_get_arb_finder + +arb_finder = bot._get_arb_finder("multi_pairwise_all") +assert arb_finder.__name__ == "FindArbitrageMultiPairwiseAll", f"[NBTest64 TestMultiPairwiseAll Mode] Expected arb_finder class name name = FindArbitrageMultiPairwiseAll, found {arb_finder.__name__}" + +# ## Test_Combos_and_Tokens + +# + +arb_finder = bot._get_arb_finder("multi_pairwise_all") +finder2 = arb_finder( + flashloan_tokens=flashloan_tokens, + CCm=CCm, + mode="bothin", + result=bot.AO_TOKENS, + ConfigObj=bot.ConfigObj, + ) +all_tokens, combos = finder2.find_arbitrage() + +assert type(all_tokens) == set, f"[NBTest64 TestMultiPairwiseAll Mode] all_tokens is wrong data type. Expected set, found: {type(all_tokens)}" +assert type(combos) == list, f"[NBTest64 TestMultiPairwiseAll Mode] combos is wrong data type. Expected list, found: {type(combos)}" +assert len(all_tokens) > 100, f"[NBTest64 TestMultiPairwiseAll Mode] Using wrong dataset, expected at least 100 tokens, found {len(all_tokens)}" +assert len(combos) > 1000, f"[NBTest64 TestMultiPairwiseAll Mode] Using wrong dataset, expected at least 100 combos, found {len(combos)}" +# - + +# ## Test_Expected_Output + +# + +arb_finder = bot._get_arb_finder("multi_pairwise_all") +finder = arb_finder( + flashloan_tokens=flashloan_tokens, + CCm=CCm, + mode="bothin", + result=bot.AO_CANDIDATES, + ConfigObj=bot.ConfigObj, + ) +r = finder.find_arbitrage() + +multi_carbon_count = 0 +carbon_wrong_direction_count = 0 +for arb in r: + ( + best_profit, + best_trade_instructions_df, + best_trade_instructions_dic, + best_src_token, + best_trade_instructions, + ) = arb + if len(best_trade_instructions_dic) > 2: + multi_carbon_count += 1 + carbon_tkn_in = None + for trade in best_trade_instructions_dic: + if "-" in trade["cid"]: + if carbon_tkn_in is None: + carbon_tkn_in = trade["tknin"] + else: + if trade["tknin"] not in carbon_tkn_in: + carbon_wrong_direction_count += 1 + + + +assert len(r) >= 25, f"[NBTest64 TestMultiPairwiseAll Mode] Expected at least 25 arbs, found {len(r)}" +assert multi_carbon_count > 0, f"[NBTest64 TestMultiPairwiseAll Mode] Not finding arbs with multiple Carbon curves." +assert carbon_wrong_direction_count == 0, f"[NBTest64 TestMultiPairwiseAll Mode] Expected all Carbon curves to have the same tkn in and tkn out. Mixing is currently not supported." +# - + + diff --git a/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.ipynb b/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.ipynb index 698c71ef0..3f8a582dd 100644 --- a/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.ipynb +++ b/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "84fa264b", "metadata": { "ExecuteTime": { @@ -10,7 +10,30 @@ "start_time": "2023-07-09T13:54:12.514167Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ConstantProductCurve v3.3.1 (05/Oct/2023)\n", + "CarbonBot v3-b2.2 (20/June/2023)\n", + "UniswapV2 v0.0.2 (2023-08-27)\n", + "UniswapV3 v0.0.2 (2023-08-27)\n", + "CarbonV1 v0.0.2 (2023-08-27)\n", + "BancorV3 v0.0.2 (2023-08-27)\n", + "imported m, np, pd, plt, os, sys, decimal; defined iseq, raises, require\n", + "Version = 3-b2.2 [requirements >= 3.0 is met]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Kveen\\PycharmProjects\\fastlane-bot\\venv_11\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + } + ], "source": [ "# coding=utf-8\n", "\"\"\"\n", @@ -54,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "a51e5ec2", "metadata": { "ExecuteTime": { @@ -62,7 +85,21 @@ "start_time": "2023-07-09T13:54:12.517536Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-01-08 12:49:14,813 [fastlane:INFO] - \n", + "2024-01-08 12:49:14,814 [fastlane:INFO] - **********************************************\n", + "2024-01-08 12:49:14,815 [fastlane:INFO] - The logging path is set to: logs/20240108-124914\\bot.log\n", + "2024-01-08 12:49:14,815 [fastlane:INFO] - **********************************************\n", + "2024-01-08 12:49:14,816 [fastlane:INFO] - \n", + "2024-01-08 12:49:18,630 [fastlane:INFO] - Time taken to add initial pools: 0.10309934616088867\n", + "2024-01-08 12:49:18,633 [fastlane:INFO] - Initializing the bot...\n" + ] + } + ], "source": [ "C = cfg = Config.new(config=Config.CONFIG_MAINNET)\n", "cfg.DEFAULT_MIN_PROFIT_GAS_TOKEN = 0.00001\n", @@ -175,7 +212,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "c8f41237", "metadata": {}, "outputs": [], @@ -193,7 +230,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "84cf37eb", "metadata": {}, "outputs": [], @@ -212,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "b1f40498", "metadata": {}, "outputs": [], @@ -231,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "810b2428", "metadata": {}, "outputs": [], @@ -250,12 +287,12 @@ "id": "e703ba6b", "metadata": {}, "source": [ - "### Test_find_arbitrage" + "### Test_find_arbitrage_single" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 7, "id": "48e2f5a1", "metadata": {}, "outputs": [ @@ -317,12 +354,131 @@ "assert len(r) >= 58, f\"[TestMultiTriangleMode] Expected at least 58 arbs, found {len(r)}\"" ] }, + { + "cell_type": "markdown", + "id": "94ecb9d7", + "metadata": {}, + "source": [ + "## Test Triangle Single" + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "85e50992", "metadata": {}, "outputs": [], + "source": [ + "arb_finder = bot._get_arb_finder(\"triangle\")\n", + "assert arb_finder.__name__ == \"ArbitrageFinderTriangleSingle\", f\"[TestMultiTriangleMode] Expected arb_finder class name name = ArbitrageFinderTriangleSingle, found {arb_finder.__name__}\"" + ] + }, + { + "cell_type": "markdown", + "id": "022a1d50", + "metadata": {}, + "source": [ + "## Test_combos_triangle_single" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "02c4fc69", + "metadata": {}, + "outputs": [], + "source": [ + "arb_finder = bot._get_arb_finder(\"triangle\")\n", + "finder2 = arb_finder(\n", + " flashloan_tokens=flashloan_tokens,\n", + " CCm=CCm,\n", + " mode=\"bothin\",\n", + " result=bot.AO_TOKENS,\n", + " ConfigObj=bot.ConfigObj,\n", + " )\n", + "combos = finder2.get_combos(flashloan_tokens=flashloan_tokens, CCm=CCm, arb_mode=\"multi_triangle\")\n", + "assert len(combos) >= 1225, f\"[TestMultiTriangleMode] Using wrong dataset, expected at least 1225 combos, found {len(combos)}\"" + ] + }, + { + "cell_type": "markdown", + "id": "fc2ad811", + "metadata": {}, + "source": [ + "## Test_Find_Arbitrage_Single" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "c160c9a0", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Kveen\\PycharmProjects\\fastlane-bot\\resources\\NBTest\\fastlane_bot\\tools\\cpc.py:1463: RuntimeWarning: divide by zero encountered in scalar divide\n", + " p = pvec[self.tknx] / pvec[self.tkny]\n", + "c:\\Users\\Kveen\\PycharmProjects\\fastlane-bot\\resources\\NBTest\\fastlane_bot\\tools\\cpc.py:1463: RuntimeWarning: divide by zero encountered in scalar divide\n", + " p = pvec[self.tknx] / pvec[self.tkny]\n", + "c:\\Users\\Kveen\\PycharmProjects\\fastlane-bot\\resources\\NBTest\\fastlane_bot\\tools\\cpc.py:1463: RuntimeWarning: divide by zero encountered in scalar divide\n", + " p = pvec[self.tknx] / pvec[self.tkny]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "900\n" + ] + } + ], + "source": [ + "arb_finder = bot._get_arb_finder(\"triangle\")\n", + "finder = arb_finder(\n", + " flashloan_tokens=flashloan_tokens,\n", + " CCm=CCm,\n", + " mode=\"bothin\",\n", + " result=bot.AO_CANDIDATES,\n", + " ConfigObj=bot.ConfigObj,\n", + " )\n", + "r = finder.find_arbitrage()\n", + "multi_carbon_count = 0\n", + "for arb in r:\n", + " (\n", + " best_profit,\n", + " best_trade_instructions_df,\n", + " best_trade_instructions_dic,\n", + " best_src_token,\n", + " best_trade_instructions,\n", + " ) = arb\n", + " if len(best_trade_instructions_dic) > 3:\n", + " multi_carbon_count += 1\n", + " tkn_in = None\n", + " tkn_out = None\n", + " # Find the first Carbon Curve to establish tknin and tknout\n", + " for curve in best_trade_instructions_dic:\n", + " if \"-0\" in curve['cid'] or \"-1\" in curve['cid']:\n", + " tkn_in = curve[\"tknin\"]\n", + " tknout = curve[\"tknout\"]\n", + " break\n", + " for curve in best_trade_instructions_dic:\n", + " if \"-0\" in curve['cid'] or \"-1\" in curve['cid']:\n", + " if curve[\"tknin\"] in [tkn_in, tkn_out] and curve[\"tknout\"] in [tkn_in, tkn_out]:\n", + " assert curve[\"tknin\"] in tkn_in, f\"[TestMultiTriangleMode] Finding Carbon curves in opposite directions - not supported in this mode.\"\n", + " assert curve[\"tknout\"] in tkn_out, f\"[TestMultiTriangleMode] Finding Carbon curves in opposite directions - not supported in this mode.\"\n", + "\n", + "assert multi_carbon_count == 0, f\"[TestMultiTriangleMode] Expected 0 arbs with multiple Carbon curves for Triangle Single mode, found {multi_carbon_count}.\"\n", + "assert len(r) >= 58, f\"[TestMultiTriangleMode] Expected at least 58 arbs, found {len(r)}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b890c9b", + "metadata": {}, + "outputs": [], "source": [] } ], diff --git a/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.py b/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.py index f011cd082..17aa51e0a 100644 --- a/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.py +++ b/resources/NBTest/NBTest_901_TestMultiTriangleModeSlow.py @@ -13,6 +13,7 @@ # name: python3 # --- +# + # coding=utf-8 """ This module contains the tests for the exchanges classes @@ -43,6 +44,7 @@ plt.rcParams['figure.figsize'] = [12,6] from fastlane_bot import __VERSION__ require("3.0", __VERSION__) +# - # # Multi Mode [NB038] @@ -180,7 +182,7 @@ def init_bot(mgr: Manager) -> CarbonBot: # print(f"found {count} pools for {ex}") # - -# ### Test_find_arbitrage +# ### Test_find_arbitrage_single # + arb_finder = bot._get_arb_finder("multi_triangle") @@ -221,4 +223,63 @@ def init_bot(mgr: Manager) -> CarbonBot: assert len(r) >= 58, f"[TestMultiTriangleMode] Expected at least 58 arbs, found {len(r)}" # - +# ## Test Triangle Single + +arb_finder = bot._get_arb_finder("triangle") +assert arb_finder.__name__ == "ArbitrageFinderTriangleSingle", f"[TestMultiTriangleMode] Expected arb_finder class name name = ArbitrageFinderTriangleSingle, found {arb_finder.__name__}" + +# ## Test_combos_triangle_single + +arb_finder = bot._get_arb_finder("triangle") +finder2 = arb_finder( + flashloan_tokens=flashloan_tokens, + CCm=CCm, + mode="bothin", + result=bot.AO_TOKENS, + ConfigObj=bot.ConfigObj, + ) +combos = finder2.get_combos(flashloan_tokens=flashloan_tokens, CCm=CCm, arb_mode="multi_triangle") +assert len(combos) >= 1225, f"[TestMultiTriangleMode] Using wrong dataset, expected at least 1225 combos, found {len(combos)}" + +# ## Test_Find_Arbitrage_Single + +# + +arb_finder = bot._get_arb_finder("triangle") +finder = arb_finder( + flashloan_tokens=flashloan_tokens, + CCm=CCm, + mode="bothin", + result=bot.AO_CANDIDATES, + ConfigObj=bot.ConfigObj, + ) +r = finder.find_arbitrage() +multi_carbon_count = 0 +for arb in r: + ( + best_profit, + best_trade_instructions_df, + best_trade_instructions_dic, + best_src_token, + best_trade_instructions, + ) = arb + if len(best_trade_instructions_dic) > 3: + multi_carbon_count += 1 + tkn_in = None + tkn_out = None + # Find the first Carbon Curve to establish tknin and tknout + for curve in best_trade_instructions_dic: + if "-0" in curve['cid'] or "-1" in curve['cid']: + tkn_in = curve["tknin"] + tknout = curve["tknout"] + break + for curve in best_trade_instructions_dic: + if "-0" in curve['cid'] or "-1" in curve['cid']: + if curve["tknin"] in [tkn_in, tkn_out] and curve["tknout"] in [tkn_in, tkn_out]: + assert curve["tknin"] in tkn_in, f"[TestMultiTriangleMode] Finding Carbon curves in opposite directions - not supported in this mode." + assert curve["tknout"] in tkn_out, f"[TestMultiTriangleMode] Finding Carbon curves in opposite directions - not supported in this mode." + +assert multi_carbon_count == 0, f"[TestMultiTriangleMode] Expected 0 arbs with multiple Carbon curves for Triangle Single mode, found {multi_carbon_count}." +assert len(r) >= 58, f"[TestMultiTriangleMode] Expected at least 58 arbs, found {len(r)}" +# - +