Source code for tradeexecutor.strategy.dust

"""Dust amounts and epsilon rounding.

Because of very small and very accurate token units,
a lot of trades may end up having rounding artifacts.
We need to deal with these rounding artifacts by checking for "dust".

"""
from _decimal import Decimal
from decimal import Decimal

from tradeexecutor.state.identifier import TradingPairIdentifier, AssetIdentifier
from tradeexecutor.state.types import Percent

#: The absolute number of tokens we consider the value to be zero
#:
#:
#: Because of funny %s of values divided near zero,
#: we cannot use relative comparison near zero values.
#:
#:
DEFAULT_DUST_EPSILON = Decimal(10 ** -4)


#: The default % we allow the balance to drift before we consider it a mismatch.
#:
#: Set to 5 BPS
#:
DEFAULT_RELATIVE_EPSILON = 5 * 10 ** -4



[docs]def get_dust_epsilon_for_pair(pair: TradingPairIdentifier) -> Decimal: """Get the dust threshold for a trading pair. :param pair: Trading pair identifier. :return: Maximum amount of units we consider "zero". """ return get_dust_epsilon_for_asset(pair.base)
[docs]def get_dust_epsilon_for_asset(asset: AssetIdentifier) -> Decimal: """Get the dust threshold for a trading pair. :param pair: Trading pair identifier. :return: Maximum amount of units we consider "zero". """ # Hardcoded rules for now. # Some practical problems we have run across in backtesting. # We have wrapped and non-wrapped token symbols as we are backtesting both on DEX and CEX data if asset.token_symbol in ("WBTC", "BTC"): return Decimal(10 ** -7) elif asset.token_symbol in ("ETH", "WETH"): return Decimal(10 ** -7) elif asset.token_symbol in ("USDC", "USDC.e"): return Decimal(0.1) elif asset.token_symbol in ("aPolUSDC", "aEthUSDC"): return Decimal(0.1) else: return DEFAULT_DUST_EPSILON
[docs]def get_relative_epsilon_for_asset(asset: AssetIdentifier) -> Percent: """Get the relative threshold for a trading pair. :param pair: Trading pair identifier. :return: Maximum amount of units we consider "zero". """ if asset.token_symbol in ("aPolUSDC", "USDC"): # Temp allow 0.5% tolerance return 0.005 # 5 BPS return DEFAULT_RELATIVE_EPSILON
[docs]def get_relative_epsilon_for_pair(pair: TradingPairIdentifier) -> Percent: return get_relative_epsilon_for_asset(pair.base)