Skip to content

Commit

Permalink
Reuse function ArbitrageFinderBase.calculate_profit in bot.py
Browse files Browse the repository at this point in the history
  • Loading branch information
barak manos committed May 27, 2024
1 parent 37b804f commit 7015fe5
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 50 deletions.
56 changes: 17 additions & 39 deletions fastlane_bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def run(

arb_opp = rand_item(list_of_items=arb_opps, num_of_items=randomizer)

tx_hash, tx_receipt = self._handle_trade_instructions(CCm, arb_mode, arb_opp, replay_from_block)
tx_hash, tx_receipt = self._handle_trade_instructions(arb_finder, arb_mode, arb_opp, replay_from_block)

if tx_hash:
tx_status = ["failed", "succeeded"][tx_receipt["status"]] if tx_receipt else "pending"
Expand All @@ -316,18 +316,18 @@ def run(

def calculate_profit(
self,
CCm: CPCContainer,
arb_finder: ArbitrageFinderBase,
best_profit: Decimal,
fl_token: str,
flashloan_fee_amt: int = 0,
) -> Tuple[Decimal, Decimal]:
"""
Calculate the actual profit in USD.
Calculate the best profit in GAS token and in USD.
Parameters
----------
CCm: CPCContainer
The container.
arb_finder: ArbitrageFinderBase
The arbitrage finder.
best_profit: Decimal
The best profit.
fl_token: str
Expand All @@ -340,45 +340,23 @@ def calculate_profit(
Tuple[Decimal, Decimal]
best_profit_gastkn, best_profit_usd.
"""
self.ConfigObj.logger.debug(f"[bot.calculate_profit] best_profit, fl_token, flashloan_fee_amt: {best_profit, fl_token, flashloan_fee_amt}")
sort_sequence = ['bancor_v2','bancor_v3'] + self.ConfigObj.UNI_V2_FORKS + self.ConfigObj.UNI_V3_FORKS

flashloan_fee_amt_fl_token = Decimal(str(flashloan_fee_amt))
if fl_token not in [self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS]:
price_curves = get_prices_simple(CCm, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, fl_token)
sorted_price_curves = custom_sort(price_curves, sort_sequence, self.ConfigObj.CARBON_V1_FORKS)
self.ConfigObj.logger.debug(f"[bot.calculate_profit sort_sequence] {sort_sequence}")
self.ConfigObj.logger.debug(f"[bot.calculate_profit price_curves] {price_curves}")
self.ConfigObj.logger.debug(f"[bot.calculate_profit sorted_price_curves] {sorted_price_curves}")
if len(sorted_price_curves)>0:
fltkn_gastkn_conversion_rate = sorted_price_curves[0][-1]
flashloan_fee_amt_gastkn = Decimal(str(flashloan_fee_amt_fl_token)) / Decimal(str(fltkn_gastkn_conversion_rate))
best_profit_gastkn = Decimal(str(best_profit)) / Decimal(str(fltkn_gastkn_conversion_rate)) - flashloan_fee_amt_gastkn
self.ConfigObj.logger.debug(f"[bot.calculate_profit] GASTOKEN: {fltkn_gastkn_conversion_rate, best_profit_gastkn}")
else:
self.ConfigObj.logger.error(
f"[bot.calculate_profit] Failed to get conversion rate for {fl_token} and {self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS}. Raise"
)
raise
else:
best_profit_gastkn = best_profit - flashloan_fee_amt_fl_token
self.ConfigObj.logger.debug(f"[bot.calculate_profit]: {best_profit, fl_token, flashloan_fee_amt}")

src_profit = Decimal(str(best_profit)) - Decimal(str(flashloan_fee_amt))
best_profit_gastkn = arb_finder.calculate_profit(fl_token, src_profit)
self.ConfigObj.logger.debug(f"[bot.calculate_profit] best_profit_gastkn: {best_profit_gastkn}")

try:
price_curves_usd = get_prices_simple(CCm, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, self.ConfigObj.STABLECOIN_ADDRESS)
sorted_price_curves_usd = custom_sort(price_curves_usd, sort_sequence, self.ConfigObj.CARBON_V1_FORKS)
self.ConfigObj.logger.debug(f"[bot.calculate_profit price_curves_usd] {price_curves_usd}")
self.ConfigObj.logger.debug(f"[bot.calculate_profit sorted_price_curves_usd] {sorted_price_curves_usd}")
usd_gastkn_conversion_rate = Decimal(str(sorted_price_curves_usd[0][-1]))
best_profit_usd = 1 / arb_finder.calculate_profit(self.ConfigObj.STABLECOIN_ADDRESS, 1 / src_profit)
except Exception:
usd_gastkn_conversion_rate = Decimal("NaN")
best_profit_usd = Decimal("NaN")
self.ConfigObj.logger.debug(f"[bot.calculate_profit] best_profit_usd: {best_profit_usd}")

best_profit_usd = best_profit_gastkn * usd_gastkn_conversion_rate
self.ConfigObj.logger.debug(f"[bot.calculate_profit] {'GASTOKEN', best_profit_gastkn, usd_gastkn_conversion_rate, best_profit_usd, 'USD'}")
return best_profit_gastkn, best_profit_usd

def _handle_trade_instructions(
self,
CCm: CPCContainer,
arb_finder: ArbitrageFinderBase,
arb_mode: str,
arb_opp: dict,
replay_from_block: int = None
Expand All @@ -391,8 +369,8 @@ def _handle_trade_instructions(
Parameters
----------
CCm: CPCContainer
The container.
arb_finder: ArbitrageFinderBase
The arbitrage finder.
arb_mode: str
The arbitrage mode.
arb_opp: dictionary
Expand Down Expand Up @@ -463,7 +441,7 @@ def _handle_trade_instructions(

# Calculate the best profit
best_profit_gastkn, best_profit_usd = self.calculate_profit(
CCm, flashloan_tkn_profit, fl_token, flashloan_fee_amt
arb_finder, flashloan_tkn_profit, fl_token, flashloan_fee_amt
)

# Check if the best profit is greater than the minimum profit
Expand Down
19 changes: 8 additions & 11 deletions fastlane_bot/modes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,18 @@ def find_arbitrage(self) -> Dict[List[Any], List[Any]]:
...

def get_profit(self, src_token: str, optimization, trade_instructions_df):
profit = self.calculate_profit(src_token, -optimization.result, self.CCm)
profit = self.calculate_profit(src_token, -optimization.result)
return profit if profit.is_finite() and profit > self.ConfigObj.DEFAULT_MIN_PROFIT_GAS_TOKEN and is_net_change_small(trade_instructions_df) else None

def calculate_profit(self, src_token: str, src_profit: float, CCm: Any) -> Decimal:
def calculate_profit(self, src_token: str, src_profit: float) -> Decimal:
"""
Calculate profit based on the source token.
"""
if src_token not in [self.ConfigObj.NATIVE_GAS_TOKEN_ADDRESS, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS]:
sort_sequence = ['bancor_v2', 'bancor_v3', 'uniswap_v2', 'uniswap_v3']
price_curves = get_prices_simple(CCm, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, src_token)
sort_sequence = ['bancor_v2', 'bancor_v3'] + self.ConfigObj.UNI_V2_FORKS + self.ConfigObj.UNI_V3_FORKS
price_curves = get_prices_simple(self.CCm, self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS, src_token)
sorted_price_curves = custom_sort(price_curves, sort_sequence, self.ConfigObj.CARBON_V1_FORKS)
self.ConfigObj.logger.debug(f"[modes.base.calculate_profit sort_sequence] {sort_sequence}")
self.ConfigObj.logger.debug(f"[modes.base.calculate_profit price_curves] {price_curves}")
self.ConfigObj.logger.debug(f"[modes.base.calculate_profit sorted_price_curves] {sorted_price_curves}")
assert len(sorted_price_curves) > 0, f"[modes.base.calculate_profit] Failed to get conversion rate for {src_token} and {self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS}"
assert len(sorted_price_curves) > 0, f"Failed to get conversion rate for {src_token} and {self.ConfigObj.WRAPPED_GAS_TOKEN_ADDRESS}"
return Decimal(str(src_profit)) / Decimal(str(sorted_price_curves[0][-1]))
return Decimal(str(src_profit))

Expand All @@ -67,9 +64,9 @@ def is_net_change_small(trade_instructions_df) -> bool:
return False

def get_prices_simple(CCm, dst_token, src_token):
curve_prices = [(CC.params['exchange'],CC.descr,CC.cid,CC.p) for CC in CCm.bytknx(dst_token).bytkny(src_token)]
curve_prices += [(CC.params['exchange'],CC.descr,CC.cid,1/CC.p) for CC in CCm.bytknx(src_token).bytkny(dst_token)]
return curve_prices
curve_prices_1 = [(CC.params['exchange'], CC.descr, CC.cid, CC.p / 1) for CC in CCm.bytknx(dst_token).bytkny(src_token)]
curve_prices_2 = [(CC.params['exchange'], CC.descr, CC.cid, 1 / CC.p) for CC in CCm.bytknx(src_token).bytkny(dst_token)]
return curve_prices_1 + curve_prices_2

def custom_sort(data, sort_sequence, carbon_v1_forks):
sort_order = {key: index for index, key in enumerate(sort_sequence) if key not in carbon_v1_forks}
Expand Down

0 comments on commit 7015fe5

Please sign in to comment.