Finding low fee trading pairs#
An example to list low fee (5 BPS) Uniswap v3 pairs across different blockchains.
You can also explore this data using the website search. Here we write Python filters to further narrow down search results.
Preface#
Most DEX pairs are low liquidity pairs with 30 BPS fee. These pairs are not well-suitable for traditional technical indicator based trading algorithms. They can be still traded, but strategies need to be non-single pair, portfolio construction model ones.
In this example we construct a list of pairs that have low LP fees and meet volume threshold for automated trading.
Create a data client#
First, let’s create Trading Strategy dataset client.
[1]:
from tradingstrategy.client import Client
client = Client.create_jupyter_client()
Started Trading Strategy in Jupyter notebook environment, configuration is stored in /Users/moo/.tradingstrategy
Download exchange and pair data#
[2]:
from tradingstrategy.exchange import ExchangeUniverse
from pyarrow import Table
# Exchange map data is so small it does not need any decompression
exchange_universe: ExchangeUniverse = client.fetch_exchange_universe()
# Decompress the pair dataset to Python map
columnar_pair_table: Table = client.fetch_pair_universe()
print(f"Total pairs {len(columnar_pair_table)}, total exchanges {len(exchange_universe.exchanges)}")
Total pairs 168541, total exchanges 4352
Filtering pairs with 5 BPS fee on Uniswap 3#
Get a list of pairs
[3]:
from tradingstrategy.stablecoin import ALL_STABLECOIN_LIKE
import pandas as pd
from tradingstrategy.pair import filter_for_stablecoins
from tradingstrategy.pair import StablecoinFilteringMode
fee_tier = 5 # BPS
pairs_df = columnar_pair_table.to_pandas()
low_fee_pairs: pd.DataFrame = pairs_df.loc[
(pairs_df["exchange_slug"] == "uniswap-v3") &
(pairs_df["fee"] == fee_tier) # BPS
]
print(f"Found {len(low_fee_pairs)} total pairs at {fee_tier} BPS fee tier")
# Filter out stablecoin pairs,
# because trading dollars to dollars do not make trading sense
low_fee_pairs = filter_for_stablecoins(low_fee_pairs, StablecoinFilteringMode.only_volatile_pairs)
print(f"Found {len(low_fee_pairs)} volatile pairs quoted in any token")
stablecoin_quoted_pairs = low_fee_pairs.loc[low_fee_pairs["quote_token_symbol"].isin(ALL_STABLECOIN_LIKE)]
print(f"Found {len(stablecoin_quoted_pairs)} volatile pairs quoted in a stablecoin")
# Assume no volume data is zero volume
stablecoin_quoted_pairs = stablecoin_quoted_pairs.fillna(0)
volume_threshold_30d = 1_000_000
volume_pairs = stablecoin_quoted_pairs.loc[stablecoin_quoted_pairs["buy_volume_30d"] >= volume_threshold_30d]
print(f"Found {len(volume_pairs)} pairs with enough volume")
Found 373 total pairs at 5 BPS fee tier
Found 308 volatile pairs quoted in any token
Found 156 volatile pairs quoted in a stablecoin
Found 13 pairs with enough volume
Print out pairs in Python format#
Write out pairs in a format that is ready to use for trading strategy Python code.
[4]:
from tradingstrategy.pair import DEXPair
from tradingstrategy.chain import ChainId
# What's monthly volume we want to consider
volume_filter = 1_000_000
print("[")
for idx, pair_row in volume_pairs.iterrows():
pair: DEXPair = DEXPair.create_from_row(pair_row)
chain_id = ChainId(pair.chain_id)
exchange_slug = pair.exchange_slug
link = pair.get_trading_pair_page_url()
vol_m = pair.volume_30d / 1_000_000
print(f' (ChainId.{chain_id.name}, "{exchange_slug}", "{pair.base_token_symbol}", "{pair.quote_token_symbol}", {fee_tier / 10_000}), # {vol_m:.2f}M vol, {link}')
print("]")
[
(ChainId.ethereum, "uniswap-v3", "WBTC", "USDC", 0.0005), # 52.07M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/wbtc-usdc-fee-5
(ChainId.ethereum, "uniswap-v3", "XSGD", "USDC", 0.0005), # 9.78M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/xsgd-usdc-fee-5
(ChainId.ethereum, "uniswap-v3", "WBTC", "USDT", 0.0005), # 4.57M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/wbtc-usdt-fee-5
(ChainId.ethereum, "uniswap-v3", "FRAX", "USDT", 0.0005), # 5.58M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/frax-usdt-fee-5
(ChainId.ethereum, "uniswap-v3", "GUSD", "USDC", 0.0005), # 4.46M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/gusd-usdc-fee-5
(ChainId.ethereum, "uniswap-v3", "WETH", "USDT", 0.0005), # 1799.41M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/eth-usdt-fee-5
(ChainId.ethereum, "uniswap-v3", "FRAX", "USDC", 0.0005), # 2.70M vol, https://tradingstrategy.ai/trading-view/ethereum/uniswap-v3/frax-usdc-fee-5
(ChainId.polygon, "uniswap-v3", "WMATIC", "USDT", 0.0005), # 100.23M vol, https://tradingstrategy.ai/trading-view/polygon/uniswap-v3/matic-usdt-fee-5
(ChainId.polygon, "uniswap-v3", "WMATIC", "USDC", 0.0005), # 364.27M vol, https://tradingstrategy.ai/trading-view/polygon/uniswap-v3/matic-usdc-fee-5
(ChainId.arbitrum, "uniswap-v3", "WBTC", "USDC", 0.0005), # 4.16M vol, https://tradingstrategy.ai/trading-view/arbitrum/uniswap-v3/wbtc-usdc-fee-5
(ChainId.arbitrum, "uniswap-v3", "WETH", "USDC", 0.0005), # 3995.54M vol, https://tradingstrategy.ai/trading-view/arbitrum/uniswap-v3/eth-usdc-fee-5
(ChainId.arbitrum, "uniswap-v3", "WETH", "USDT", 0.0005), # 1010.93M vol, https://tradingstrategy.ai/trading-view/arbitrum/uniswap-v3/eth-usdt-fee-5
(ChainId.arbitrum, "uniswap-v3", "ARB", "USDC", 0.0005), # 797.72M vol, https://tradingstrategy.ai/trading-view/arbitrum/uniswap-v3/arb-usdc-fee-5
]
[4]: