Loading exchange, pair, and candlestick data for Uniswap V3#

In this notebook, we create a basic example of how to load:

  1. Exchanges

  2. Pairs

  3. Candle data

  • We use the TradingStrategy API to get data for 3 pairs on Uniswap V3

  • This is done for 3 pairs: eth_usdc, eth_usdt, and usdt_usdc

The following code block shows an example of some the data from the api

Load exchanges and pairs#

First, let’s create a TradingStrategy dataset client#

[1]:
from tradingstrategy.client import Client

client = Client.create_jupyter_client()
Started Trading Strategy in Jupyter notebook environment, configuration is stored in /home/alex/.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 185803, total exchanges 4668
[3]:
pairs_df = columnar_pair_table.to_pandas()
display(pairs_df.head())
pair_id chain_id exchange_id address token0_address token1_address token0_symbol token1_symbol dex_type base_token_symbol ... sell_count_all_time buy_volume_all_time sell_volume_all_time buy_count_30d sell_count_30d buy_volume_30d sell_volume_30d buy_tax transfer_tax sell_tax
0 1 1 1 0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 USDC WETH uniswap_v2 WETH ... 2366545.0 2.169846e+10 2.151672e+10 27214.0 21778.0 4.145122e+07 4.134013e+07 0.0 0.0 0.0
1 3 1 1 0x12ede161c702d1494612d19f05992f43aa6a26fb 0x06af07097c9eeb7fd685c692751d5c66db49c215 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 CHAI WETH uniswap_v2 CHAI ... 352.0 6.713448e+04 6.953514e+04 1.0 2.0 6.592286e+01 6.581656e+01 999.0 999.0 999.0
2 4 1 1 0xa478c2975ab1ea89e8196811f51a7b7ade33eb11 0x6b175474e89094c44da98b954eedeac495271d0f 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 DAI WETH uniswap_v2 WETH ... 753814.0 7.832598e+09 7.730437e+09 2626.0 3131.0 3.699619e+06 3.692982e+06 0.0 0.0 0.0
3 5 1 1 0x07f068ca326a469fc1d87d85d448990c8cba7df9 0x408e41876cccdc0f92210600ef50372656052a38 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 REN USDC uniswap_v2 REN ... 565.0 4.783008e+04 4.966043e+04 NaN NaN NaN NaN 999.0 999.0 999.0
4 6 1 1 0xae461ca67b15dc8dc81ce7615e0320da1a9ab8d5 0x6b175474e89094c44da98b954eedeac495271d0f 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 DAI USDC uniswap_v2 DAI ... 86735.0 2.862940e+08 2.853550e+08 172.0 228.0 2.170395e+05 2.190588e+05 0.0 0.0 0.0

5 rows × 36 columns

Filtering pairs to have 5 BPS fee on Uniswap V3#

[4]:
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

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 does not make trading sense (unless in arbitrage, which is not covered here)
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 420 total pairs at 5 BPS fee tier
Found 352 volatile pairs quoted in any token
Found 176 volatile pairs quoted in a stablecoin
Found 17 pairs with enough volume

Get candle data using API#

This is an example of gettting data directly from the TradingStrategy API. Visit the API explorer for the full API documentation.

Note: This is a slow method and shouldn’t be used for actual backtesting purposes. For backtesting, candle data comes from the TradingStrategyUniverse (created by the create_trading_universe function). Visit the strategy examples section for backtesting examples.

[5]:
import requests
import pandas as pd

pairs = {
    'eth_usdc': 'https://tradingstrategy.ai/api/candles?pair_id=2697765&exchange_type=uniswap_v3&time_bucket=4h',
    'usdt_usdc': 'https://tradingstrategy.ai/api/candles?pair_id=2711887&exchange_type=uniswap_v3&time_bucket=4h',
    'eth_usdt': 'https://tradingstrategy.ai/api/candles?pair_id=2697770&exchange_type=uniswap_v3&time_bucket=4h'

}

def get_candles(url: str) -> pd.DataFrame:
    x = requests.get(url)
    json = x.json()
    (key, value) = json.popitem()
    candles = pd.DataFrame.from_dict(value)
    candles.rename(columns = {'ts':'date','o':'open', 'h':'high','l':'low','c':'close','v':'volume'}, inplace = True)
    candles['timestamp'] = pd.to_datetime(candles['date'])
    candles = candles.set_index('timestamp')
    return candles

pair_data = dict([ (k,get_candles(r)) for k,r in pairs.items()])

pair_data['usdt_usdc'].head()
[5]:
date open high low close volume xr b s tc bv sv
timestamp
2023-07-23 08:00:00 2023-07-23T08:00:00 1.0000 1.0001 1.0000 1.0001 1.153055e+06 1.0 None None None None None
2023-07-23 12:00:00 2023-07-23T12:00:00 1.0001 1.0001 1.0001 1.0001 5.719236e+05 1.0 None None None None None
2023-07-23 16:00:00 2023-07-23T16:00:00 1.0001 1.0001 1.0001 1.0001 3.719233e+06 1.0 None None None None None
2023-07-23 20:00:00 2023-07-23T20:00:00 1.0001 1.0001 1.0001 1.0001 1.241179e+06 1.0 None None None None None
2023-07-24 00:00:00 2023-07-24T00:00:00 1.0001 1.0001 1.0001 1.0001 5.094711e+06 1.0 None None None None None

Visualize candlestick data#

Here we visualize the prices and volumes of each of the 3 pairs.

[6]:
from tradingstrategy.charting.candle_chart import visualise_ohlcv

def get_figure(candles: pd.DataFrame, chart_name: str):
    return visualise_ohlcv(
            candles,
            height=600,
            theme="plotly_white",
            chart_name=chart_name,
            y_axis_name="Price",
            volume_axis_name="volume",)
figures = dict([ (k,get_figure(r, k)) for k,r in pair_data.items()])

fig1 = figures['eth_usdc']
fig2 = figures['eth_usdt']
fig3 = figures['usdt_usdc']

# update titles
fig1.update_layout(title="ETH/USDC")
fig2.update_layout(title="ETH/USDT")
fig3.update_layout(title="USDT/USDC")

fig1.show()
fig2.show()
fig3.show()