Мемкойны на пару с нфт одни из моих самых нелюбимых трендов крипты, никакой технологичности, один маркетинг. Но взрывной рост в Q1 2024, привлекает внимание к нарративу мемкойнов. (По версии coingecko это самый прибыльный нарратив Q1 2024, но есть вопросы к методологии). Поэтому предлагаю попробовать, найти мемкойны на TON, попробовав собрать простенький дэшборд мемкойнов..
В статье я хочу разобрать, почему аналитические платформы мем койнов выглядят как live лента покупок этих самых мемкойнов. Пробежаться по новым API Stonfi, данные этой DEX теперь отображаются на Dexscreener, и под это появились отдельные открытые API, что сильно влияет на доступность данных(а это проблема в TON) И третье, посмотреть некоторые свои статистические гипотезы относительно пулов..
Что будем искать?
Если погуглить определение мемкойнов, то определения будут разница от пирамид нашего времени, до цифровой мем валюты, нового слова в сфере social tech.Поэтому в рамках этой статьи я предлагаю свое определение: Мемкойн это динамично растущий токен без изначального утилити, использующий механизмы Fomo для обеспечения роста. Данное определение дает мне возможность сформулировать гипотезу: Мемкойны это быстрорастущие малые проекты, а значит можно сначала отрезать крупные проекты по объему их пулов(Total Value Locked), а далее рассмотреть маленькие проекты по количеству свапов за последний, например, день.
Строим диаграмму TVL для пулов Stonfi — ищем порог за которым мемкойны
Начнем с TVL. У Stonfi есть две API v1/pools — возвращающий текущее состояние пулов и v1/stats/pools — статистика по пулам за период. Воспользуемся v1/pools, нам нужен адрес пула, адреса токенов из которых состоит пул и lp_total_supply_usd — общее предложение lp токенов пула. Lp токены это автоматически генерируемые DEX и начисляемые провайдеру ликвидности за внесения активов в пул ликвидности. Эти токены представляют собой долю комиссий, заработанных пулом ликвидности. Соответственно их предложение в долларовом эквиваленте будет отражать TVL.
import requests r = requests.get('https://api.ston.fi/v1/pools') result = r.json()['pool_list'] # упомянуть что есть еще но грузит там долго # возьмем нужные нам поля #замечу tvl храниться строкой - надо менят ь temp_pool_list = [{'pool_address': pool['address'], 'token0_address': pool['token0_address'], 'token1_address': pool['token1_address'], 'tvl': round(float(pool['lp_total_supply_usd']),2)} for pool in result] # Отсортируем sorted_pool_list = sorted(temp_pool_list, key=lambda d: d['tvl'],reverse=True) sorted_pool_list[0:5]
Отсортировав получим(данные пока не обогащаю, чтобы не выглядело рекламой тех или иных токенов):
Визуально воспринимать информацию легче, поэтому построим график:
import matplotlib.pyplot as plt fig, ax = plt.subplots() pool_addresses = [d['pool_address'][-4:] for d in sorted_pool_list] tvl_values = [d['tvl'] for d in sorted_pool_list] plt.bar(pool_addresses, tvl_values, color='skyblue',log=True) plt.xlabel('Pool Address') plt.ylabel('TVL') plt.title('TVL for Pools') plt.xticks(color='w') plt.tight_layout()
Результат:
Из графика хорошо видно, что первые пару пулов перекрывают по объему все остальные, также видно, что бывают плато, и объем залоченных средств хорошо позволяет классифицировать токены по неким лигам,от мелочи до просто огромных пулов.
Чтобы поиграться с гипотезами сделаем круговую диаграмму, разбив все пулы неким порогом, а количество пулов вынесем в название, тогда будет очень хорошо видно, например, что первые три пула по объему, содержат в себе больше половины залоченной ликвидности.
threshold = 10000000 big_pools = sum(item['tvl'] for item in sorted_pool_list if item['tvl']>=threshold) small_pools = sum(item['tvl'] for item in sorted_pool_list if item['tvl']<threshold) big_pools_count = len([item['tvl'] for item in sorted_pool_list if item['tvl']>=threshold]) small_pools_count = len([item['tvl'] for item in sorted_pool_list if item['tvl']<threshold]) labels = 'Big pools', 'Small pools' sizes = [big_pools, small_pools] fig, ax = plt.subplots() ax.pie(sizes, labels=labels) ax.set_title("Big pools count:{}, Small pools count {} ".format(big_pools_count,small_pools_count))
Получим следующую диаграмму:
На блокчейне Solana есть лаунчапад pump fun, в нем заложено ограничение на 69к долларов, т.е. вы можете запустить свой токен, но как только он вырастет выше 69к долларов он “уйдет” на крупную биржу, попробуем такой порог:
Но и здесь не без нюансов, пулы могут содержать в себе пары любых жеттонов(стандарт токенов на ТОН) или ТОН. Но в большинстве своем это пулы:
-
жеттон — TON
-
жеттон — стейблкойн
-
жеттон — Notcoin
Notcoin можно назвать самым крупным мемкойном TON’а, поэтому наш простой дэшборд стоит начать с доминации Notcoin. Проверим диаграммой:
Notcoin = 'EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT' not_pools = sum(item['tvl'] for item in sorted_pool_list if item['token0_address']==Notcoin or item['token1_address']==Notcoin ) notnot_pools = sum(item['tvl'] for item in sorted_pool_list if item['token0_address']!=Notcoin or item['token1_address']!=Notcoin ) not_count = len([item['tvl'] for item in sorted_pool_list if item['token0_address']==Notcoin or item['token1_address']==Notcoin]) notnot_count = len([item['tvl'] for item in sorted_pool_list if item['token0_address']!=Notcoin or item['token1_address']!=Notcoin]) # посчитать кол-во и вывести в название labels = 'Notcoin pools', 'Other pools count' sizes = [not_pools, notnot_pools] fig, ax = plt.subplots() ax.pie(sizes, labels=labels) ax.set_title("Notcoin pools count:{}, Other pools count {} ".format(not_count,notnot_count))
Итог:
Как можно видеть по сравнению с другими токенами Notcoin огромен и его доминацию стоит учитывать при обзоре рынка мемкойнов TON.
Проблема ликвидности
Окей, допустим вы выбрали какой-то порог TVL, и посмотрели доминацию Notcoin, но дальше рассматривать TVL бесполезно. Малые пулы страдают проблемой ликвидности — в них просто мало свапов. И заблокированная в них ликвидность никак не позволяет их сравнить.
Именно поэтому, аналитические платформы мемкойнов часто выглядит как live feed. Приложения сканируют блоки на предмет свапов в малых пулах. Это позволяет за минуту примерно увидеть какой мемкойн сейчас растет. Чтобы было понятнее как это выглядит, я собрал подобное для пулов Stonfi: https://tonhotshot.fun/
-
Сначала сканируются пулы и находится самый крупный пул до 69к TVL — царь горы
-
Далее каждый блок сканируется на транзакции в Stonfi в пулах до 69к.
Причем данные беруться из общедоступных API Stonfi о которых я упоминал ранее. Попробуем построить свой дэшборд на этих данных.
Ранжируем мемкойны на Stonfi
Данные о свапах мы будем брать из нового API созданного под Dexscreener, это API событий(export/dexscreener/v1/events). Данное API отдает все события DEX Stonfi между двумя блоками. Пускай для нашего дэшборда мы выберем период в день, где же нам взять текущий блок от которого оттолкнуться? Здесь два варианта:
Первый вариант, воспользоваться соседней ручкой export/dexscreener/v1/latest-block, она вернет последний блок обработанный бэкендом биржи, которая индексирует блокчейн и позволяет нам получить данные в агрегированном виде. Плюс данного подхода, что мы получим последний обработанный индексатором блок, минус то, что ручка отрабатывает в среднем 10 секунд и это не всегда удобно.
ltb = requests.get('https://api.ston.fi/v1/screener/latest-block') lastest_block = ltb.json()['block']['blockNumber']
Второй вариант, взять прост последний блок из блокчейна, да последний блок в блокчейне не равен последнему блоку обработанному индексатором биржи, но зато это быстро, один из вариантов как это сделать
# RPS 1 sec ltb = requests.get('https://toncenter.com/api/v3/masterchainInfo') return ltb.json()['last']['seqno']
Допустим мы возьмем все события, как убрать крупные блоки? Точно также как мы делали вначале — достать все пулы и убрать те, что нам не нужны:
def get_block_list(sorted_pool_list,threshold): Notcoin = 'EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT' return [item['pool_address'] for item in sorted_pool_list if item['tvl']>=threshold or item['token0_address'] == Notcoin or item['token1_address'] == Notcoin]
Также сразу уберем пулы с ноткойном, так как мы ищем новые мемкойны.
После сбора событий, сразу посчитаем количество используя Counter:
def count_swap_events(sorted_pool_list,threshold): blocker = get_block_list(sorted_pool_list,threshold) ltb = requests.get('https://api.ston.fi/v1/screener/latest-block') lastest_block = ltb.json()['block']['blockNumber'] start_block=lastest_block - int(86400/5) # TON "обновляет" блоки каждые 5 секунд в дне 86400 секунд payload = {'fromBlock': start_block, 'toBlock': lastest_block} r = requests.get('https://api.ston.fi/export/dexscreener/v1/events', params=payload) count_arr=[] for item in r.json()['events']: if(item['eventType']=='swap'): if(item["pairId"] not in blocker): count_arr.append(item) c = Counter() for event in count_arr: c[event["pairId"]] += 1
Чтобы зацепить еще пару ручек, обогатим наши данные используя только адрес пула, для этого с помощью /export/dexscreener/v1/pair/ достанем адреса токенов и с помощью /v1/assets/ достанем названия жетонов или TON.
def pool_pair(pool_addr): p = requests.get('https://api.ston.fi/export/dexscreener/v1/pair/{}'.format(pool_addr)) try: pair=p.json()['pool'] return jetton_name(pair['asset0Id']) +"-"+ jetton_name(pair['asset1Id']) except: return pool_addr
Здесь отмечу, что это просто туториал и весь код пишется максимально примитивно, чтобы вы могли прочитать его по диагонали. Обогатим наш Counter и отсортируем его:
def count_swap_events(sorted_pool_list,threshold): blocker = get_block_list(sorted_pool_list,threshold) ltb = requests.get('https://api.ston.fi/v1/screener/latest-block') lastest_block = ltb.json()['block']['blockNumber'] start_block=lastest_block - int(86400/5) # TON "обновляет" блоки каждые 5 секунд в дне 86400 секунд payload = {'fromBlock': start_block, 'toBlock': lastest_block} r = requests.get('https://api.ston.fi/export/dexscreener/v1/events', params=payload) count_arr=[] for item in r.json()['events']: if(item['eventType']=='swap'): if(item["pairId"] not in blocker): count_arr.append(item) c = Counter() for event in count_arr: c[event["pairId"]] += 1 enriched_arr=[] for pool in sorted(list(c.items()), key=lambda d: d[1],reverse=True)[0:30]: enriched_arr.append({"pool": pool_pair(pool[0]),'24h_swaps':pool[1]}) return enriched_arr
Получим примерно следующее:
Конечно, можно много что улучшить, но предлагаю читателю самому дособирать дэшборд, все API Stonfi можно глянуть здесь — https://api.ston.fi/swagger-ui/
Заключение
Мне нравится блокчейн TON своей технической изящностью, как минимум это не очередная копия Ethereum, которую разгоняют с помощью большого капитала без оглядки, а вообще зачем это нужно пользователю. Если вы хотите узнать больше о блокчейне TON, у меня есть опенсорсные уроки, благодаря которым вы научитесь создавать полноценные приложения на TON.
https://github.com/romanovichim/TonFunClessons_ru
Новые туториалы и дата аналитику я кидаю сюда
ссылка на оригинал статьи https://habr.com/ru/articles/820631/
Добавить комментарий