Блог им. RomellaAkumov

Как я написал скрипт для отбора лучших криптоактивов для торговли.

 

Рынок криптовалют характеризуется высокой волатильностью и большим количеством одновременно торгуемых инструментов. Для трейдера ключевой проблемой становится не столько поиск точки входа, сколько предварительный отбор активов, на которые вообще стоит обращать внимание. Ручной анализ десятков графиков требует значительных временных затрат и неизбежно приводит к субъективным ошибкам. Особенно актуально это стало на текущем крипторынке — в декабре, да и в целом во второй половина 2025 года, было огромное количество периодов с околонулевой волатильностью, что делает качественную торговлю невозможной.

Целью данной работы стало создание автоматизированного скрипта, который позволяет в реальном времени отбирать криптоактивы с признаками повышенного интереса со стороны участников рынка. В основе подхода лежит анализ динамики открытого интереса (Open Interest) и его соотношения с движением цены. В качестве платформы для оповещений я выбрал telegram — настроим бота, который будет присылать уведомления по необходимым активам.

Скрипт для вашего удобства выложен на GitHub вместе с клиентом для биржи bingx, с которым я работаю почти во всех своих статьях. Здесь открытие сделок реализовано не будет, но такая возможность сохраняется и сейчас мной проводятся тесты по полной автоматизации открытия сделок в рамках непубличного проекта, где в основе лежат именно разработанные нами сегодня уведомления.

Общая идея и постановка задачи

Open Interest отражает суммарный объём открытых фьючерсных позиций по инструменту. Рост этого показателя означает, что в рынок заходит новый капитал, а снижение — что позиции закрываются. Однако сам по себе рост Open Interest не даёт полной картины: он становится информативным только в сравнении с поведением цены.

Основная гипотеза, положенная в основу скрипта, заключается в следующем: если открытый интерес растёт быстрее, чем цена, это может указывать на фазу накопления позиций, когда участники рынка ещё не реализовали своё намерение в виде направленного движения. Такие ситуации представляют наибольший интерес для последующего анализа и торговли.

Как я написал скрипт для отбора лучших криптоактивов для торговли.гипотеза

Также нужно понять логику работы бота — откуда брать данные, какие именно периоды использовать. Среди источников данных есть как биржи, так и ончейн сервисы. Я выбрал первые, так как ончейн сервисы чаще всего платные, да и качество API binance, которое способно отдать данные даже без апи ключей и регистрации на бирже, ничуть не хуже. Будем получать через него данные об изменениях цены и открытого интереса. В качестве фильтров можно также использовать ончейн метрики, но сегодня мы пока обойдём это стороной — так как OI сам по себе — очень сильная метрика. Ну и в качестве уведомлений мы уже выбрали telegram — удобный и гибкий сервис.

Как я написал скрипт для отбора лучших криптоактивов для торговли.

Среди типов сигналов я выбираю 2 таймфрейма (временных периода) — 4 часа и 24часа. 24-х часовой период позволит находить среднесрочные идеи, 4-х часовой период же пригодится для подтверждения идеи и поиска интрадей идей. Получим следующее:

Как я написал скрипт для отбора лучших криптоактивов для торговли.

Конфигурация и параметры анализа

Теперь давайте приступим к написанию кода. Использовать будем python и ряд библиотек.

Сразу подключим используемые в скрипте библиотеки:

<code>import time
import requests
from datetime import datetime
from collections import defaultdict
from telegram import Bot
import json
from pathlib import Path</code>

Работа скрипта начинается с задания параметров, которые определяют чувствительность и характер отбора. Также сразу инициализируем бота, зададим вспомогательные переменные и функции.

<code>BINANCE_FAPI_URL = "https://fapi.binance.com"

TELEGRAM_TOKEN = ""
TELEGRAM_CHAT_ID = ""

CHECK_INTERVAL_MIN = 1

OI_4H_THRESHOLD = 7.0     # %
OI_24H_THRESHOLD = 15.0    # %

PRICE_OI_RATIO = 1.5     # price_growth <= oi_growth * ratio
MIN_OI_USDT = 5_000_000  # фильтр мусора

SIGNAL_COOLDOWN_HOURS = 3  # защита от спама

REQUEST_TIMEOUT = 5

bot = Bot(token=TELEGRAM_TOKEN)
last_signal_time = defaultdict(lambda: datetime.min)</code>

Здесь задаются минимальные значения роста открытого интереса для четырёхчасового и суточного интервалов. Коэффициент PRICE_OI_RATIO определяет допустимое соотношение между ростом цены и ростом OI. Минимальный порог OI в долларах используется для исключения неликвидных инструментов. Интервал SIGNAL_COOLDOWN_HOURS предотвращает повторную генерацию сигналов по одному и тому же активу.

Для списка пользователей, которые будут пользоваться ботом, создадим json файл, чтобы впоследствии парсить их ID оттуда

<code>USERS_FILE = Path("users.json")</code>

Функции сохранения пользователей в список и их удаления:

<code>def load_users():
    if USERS_FILE.exists():
        return set(json.loads(USERS_FILE.read_text()))
    return set()

def save_users(users):
    USERS_FILE.write_text(json.dumps(list(users)))

users = load_users() #подгружаем список при запуске скрипта</code>

Получение списка анализируемых инструментов

Перед началом анализа скрипт формирует список всех доступных фьючерсных контрактов с расчётом в USDT.

<code>def get_symbols():
    data = binance_get("/fapi/v1/exchangeInfo")
    return [
        s["symbol"]
        for s in data["symbols"]
        if s["contractType"] == "PERPETUAL"
        and s["quoteAsset"] == "USDT"
        and s["status"] == "TRADING"
    ]
</code>

Этот фрагмент гарантирует, что в анализ попадают только активные бессрочные фьючерсы. Таким образом исключаются устаревшие, приостановленные или экзотические инструменты, не представляющие практического интереса.

Для упрощения запросов к бинанс API я написал отдельную функцию binance_get, которая будет грамотно формировать и отсылать запрос:

<code>def binance_get(endpoint, params=None):
    url = BINANCE_FAPI_URL + endpoint
    r = requests.get(url, params=params, timeout=REQUEST_TIMEOUT)
    r.raise_for_status()
    return r.json()</code>

Расчёт процентных изменений

Для приведения данных к единой шкале используется универсальная функция вычисления процентного изменения.

<code>def pct(now, past):
    if past == 0:
        return 0.0
    return (now - past) / past * 100.0
</code>

Эта функция применяется как к цене, так и к открытому интересу. Использование относительных величин позволяет корректно сравнивать активы с разной ценой и капитализацией.

Получение и анализ Open Interest

Данные по открытому интересу загружаются с пятиминутным шагом и агрегируются в заданные временные окна.

<code>def get_oi_hist(symbol, limit):
    return binance_get(
        "/futures/data/openInterestHist",
        {
            "symbol": symbol,
            "period": "5m",
            "limit": limit
        }
    )
</code>

Значение limit=48 соответствует четырём часам, а limit=288 — суткам. Далее из этих данных извлекаются крайние значения для расчёта роста OI.

<code>oi_now = float(oi_4h[-1]["sumOpenInterestValue"])
oi_4h_ago = float(oi_4h[0]["sumOpenInterestValue"])
oi_24h_ago = float(oi_24h[0]["sumOpenInterestValue"])
</code>

Использование поля sumOpenInterestValue позволяет работать с денежным выражением открытых позиций, что особенно важно при фильтрации по ликвидности.

Индекс [-1] тут — самая последняя и новая свеча. Индекс [0] — самая старая (т.е. 1 необходимый нам период назад. В данном случае 4 и 24 часа назад).

Анализ динамики цены

Цена анализируется синхронно с Open Interest, на тех же временных интервалах.

<code>def get_klines(symbol, limit):
    return binance_get(
        "/fapi/v1/klines",
        {
            "symbol": symbol,
            "interval": "5m",
            "limit": limit
        }
    )</code>

Для расчётов используется цена закрытия/открытия свечи. Получить мы её можем с помощью обращения к свечам с индексами [-1] и [0], в которых мы обратимся к данным под номерами [1] — OPEN и [4] — CLOSE. Данные в свече идут в таком формате: timestamp, open, high, low, close, volume,…. И так как работаем тут с open для открытия свечи и получения цены период назад, с close для закрытия свечи и получения текущей цены, то используем индексы 1 и 4.

<code>price_now = float(klines_4h[-1][4])
price_4h_ago = float(klines_4h[0][1])
price_24h_ago = float(klines_24h[0][1])
</code>

Таким образом обеспечивается корректное сопоставление изменений цены и открытого интереса во времени.

Формирование сигнальных условий

Ключевая логика скрипта сосредоточена в сравнении темпов роста цены и OI.

<code>signal_4h = (
    oi_growth_4h >= OI_4H_THRESHOLD and
    price_growth_4h <= oi_growth_4h * PRICE_OI_RATIO
)</code>

Аналогичное условие используется для суточного интервала. Смысл этой проверки заключается в том, что рост цены допускается, но он не должен опережать рост открытого интереса. В противном случае считается, что движение уже реализовано и потеряло аналитическую ценность.

Ограничение частоты сигналов

Для предотвращения повторных уведомлений используется словарь с временными метками последнего сигнала.

<code>last_signal_time = defaultdict(lambda: datetime.min)</code>

Перед генерацией нового уведомления проверяется, прошло ли достаточное количество времени с момента предыдущего сигнала по данному инструменту. Это делает поток уведомлений управляемым и пригодным для практического использования.

Генерация и отправка уведомлений

При выполнении всех условий формируется сообщение, содержащее ключевые показатели.

<code>send_alert(
    f"<b>{symbol}</b>\n"
    f"OI 4h: {oi_growth_4h:.1f}%\n"
    f"OI 24h: {oi_growth_24h:.1f}%\n"
    f"Цена 4h: {price_growth_4h:.1f}%\n"
    f"Цена 24h: {price_growth_24h:.1f}%"
)</code>

Сообщение передаётся в Telegram и предназначено не для немедленного открытия сделки, а для фиксации факта повышенного интереса к активу. Впоследствии необходимо анализировать чарт и смотреть, действительно ли актив интересен и актуален для открытия лонговых позиций.

Функция send_alert выглядит следующим образом:

<code>def send_alert(text):
    for chat_id in users:
        try:
            bot.send_message(
                chat_id=chat_id,
                text=text,
                parse_mode="HTML"
            )
        except Exception as e:
            print(f"Telegram error {chat_id}: {e}")</code>

Основной цикл работы

Скрипт работает в непрерывном режиме, последовательно анализируя все доступные инструменты.

<code>while True:
    for symbol in symbols:
        check_symbol(symbol)
        time.sleep(0.1)
</code>

Небольшая задержка между запросами необходима для соблюдения ограничений API и стабильной работы системы.

Интерпретация результатов

Важно подчеркнуть, что данный скрипт не предсказывает направление движения цены. Его задача — выделить активы, в которых наблюдается нетипичная динамика открытого интереса. Это позволяет сузить пространство анализа и сосредоточиться на инструментах, где потенциально формируется значимое рыночное событие.

Заключение

В данной работе был рассмотрен практический пример создания скрипта для автоматического отбора криптоактивов на основе анализа открытого интереса и цены. Показано, каким образом относительно простые количественные методы могут быть использованы для фильтрации рынка и повышения эффективности анализа.

Подобный подход не заменяет торговую стратегию, но служит важным аналитическим инструментом, позволяющим работать с рынком более осознанно и структурировано.

208
#86 по плюсам

Читайте на SMART-LAB:
Фото
О топовых проектах Софтлайн в промышленности
За 2025 год Софтлайн успешно завершил огромное количество крутых и крупных проектов. В этом посте вспомним лучшие из них, в частности — для...
Подводим итоги Займера в 2025
Вот-вот новый год сменит предыдущий. Давайте вместе вспомним, чем 2025 отметился для Займера и его акционеров. 🎉 Январь: нашей компании...
Фото
❤️ Подводим итоги года вместе с инвесторами МГКЛ
🎄 Этот год мы прошли вместе с вами — нашими инвесторами. Каждый день были на связи, отвечали на вопросы, делились новостями, обсуждали...

теги блога Roman crypto_maniac

....все тэги



UPDONW
Новый дизайн