Создание торгового бота на Python с API AsterDEX

Это пошаговое руководство покажет, как создать простого торгового бота на Python, который взаимодействует с биржей AsterDEX через REST API. Мы пройдем путь от настройки окружения до размещения первого ордера.

Введение

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

Необходимые условия:

  • Установленный Python 3.6+
  • Базовое понимание работы REST API.
  • Сгенерированные ключи API на бирже AsterDEX. Если у вас их еще нет, обратитесь к нашему руководству по API.

Шаг 1: Настройка окружения и установка библиотек

Для взаимодействия с API нам понадобится библиотека `requests` для отправки HTTP-запросов. Установим ее через pip:

pip install requests

Создайте файл, например, `bot.py`, и импортируйте необходимые библиотеки. Нам также понадобятся `hmac`, `hashlib` и `time` для создания подписи запроса.

import requests
import hmac
import hashlib
import time

# Ваши API ключи (храните их в безопасности!)
API_KEY = "YOUR_API_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"

# Базовый URL API
BASE_URL = "https://fapi.asterdex.com"

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

Шаг 2: Проверка соединения с API

Давайте убедимся, что мы можем достучаться до сервера. Для этого отправим простой GET-запрос на эндпоинт `/fapi/v1/ping`.

def check_connection():
    path = "/fapi/v1/ping"
    url = BASE_URL + path
    
    try:
        response = requests.get(url)
        if response.status_code == 200:
            print("Соединение с API AsterDEX успешно установлено!")
            return True
        else:
            print(f"Ошибка! Статус-код: {response.status_code}, Ответ: {response.text}")
            return False
    except Exception as e:
        print(f"Произошла ошибка при подключении: {e}")
        return False

# Проверяем соединение
check_connection()

Если все настроено правильно, в консоли вы увидите сообщение об успешном соединении.

Шаг 3: Получение рыночных данных

Теперь получим реальные рыночные данные. Например, запросим текущую книгу ордеров (стакан) для пары `BTC/USDT`.

def get_order_book(symbol="BTCUSDT", limit=5):
    path = "/fapi/v1/depth"
    params = {
        "symbol": symbol,
        "limit": limit
    }
    url = BASE_URL + path
    
    try:
        response = requests.get(url, params=params)
        data = response.json()
        
        # Лучшая цена покупки (bid) и продажи (ask)
        best_bid = data['bids'][0][0]
        best_ask = data['asks'][0][0]
        
        print(f"--- Стакан для {symbol} ---")
        print(f"Лучшая покупка (Bid): {best_bid}")
        print(f"Лучшая продажа (Ask): {best_ask}")
        print("-----------------------")
        
        return data
        
    except Exception as e:
        print(f"Ошибка при получении стакана: {e}")
        return None

# Получаем стакан
get_order_book()

Шаг 4: Создание подписанного запроса для размещения ордера

Это самый важный шаг. Для выполнения действий с вашим счетом (например, размещение ордера) каждый запрос должен быть подписан вашим `SECRET_KEY` с использованием алгоритма HMAC SHA256. Это доказывает серверу, что запрос отправили именно вы.

Мы создадим функцию, которая будет генерировать подпись и отправлять POST-запрос.

def send_signed_request(method, path, params=None):
    if params is None:
        params = {}
    
    timestamp = int(time.time() * 1000)
    params['timestamp'] = timestamp
    
    query_string = '&'.join([f"{key}={params[key]}" for key in sorted(params)])
    
    signature = hmac.new(
        SECRET_KEY.encode('utf-8'),
        query_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    params['signature'] = signature
    
    url = BASE_URL + path
    headers = {'X-MBX-APIKEY': API_KEY}
    
    try:
        if method == 'POST':
            response = requests.post(url, headers=headers, params=params)
        elif method == 'GET':
            response = requests.get(url, headers=headers, params=params)
        else:
            return None
        
        return response.json()
        
    except Exception as e:
        print(f"Ошибка при отправке подписанного запроса: {e}")
        return None

# Пример: размещение тестового лимитного ордера на покупку
# ВАЖНО: Используйте очень маленькую сумму для теста!
def place_test_order():
    path = "/fapi/v1/order"
    
    # Параметры для лимитного ордера на покупку 0.001 BTC по цене $20,000
    # Убедитесь, что цена реалистична, иначе ордер не исполнится
    params = {
        "symbol": "BTCUSDT",
        "side": "BUY",
        "type": "LIMIT",
        "timeInForce": "GTC", # Good-Til-Canceled
        "quantity": 0.001,
        "price": 20000 
    }
    
    # Для реальной торговли добавьте параметр `test=false` или уберите его
    # Для теста можно использовать эндпоинт /fapi/v1/order/test
    # response = send_signed_request('POST', path + '/test', params)
    
    # Для реального ордера:
    # response = send_signed_request('POST', path, params)
    
    # Мы закомментировали реальный вызов, чтобы вы не разместили ордер случайно
    print("Функция для размещения ордера готова. Раскомментируйте вызов для теста.")
    # print(response)


# Вызов функции для теста
place_test_order()

Шаг 5: Собираем все вместе - простая логика бота

Теперь объединим все части в простой цикл. Логика будет примитивной, но покажет основной принцип работы бота: раз в 10 секунд проверять цену и "принимать решение".

def simple_bot_logic():
    print("Запуск простого бота...")
    
    # Условная цена, при которой мы хотим купить
    target_price = 25000.0
    
    while True:
        try:
            order_book = get_order_book("BTCUSDT")
            if order_book:
                # Берем лучшую цену продажи (ask) - по ней мы можем купить
                current_price = float(order_book['asks'][0][0])
                print(f"Текущая цена BTC: ${current_price}")
                
                if current_price < target_price:
                    print(f"Цена (${current_price}) ниже целевой (${target_price}). Время покупать!")
                    # Здесь могла бы быть логика размещения ордера
                    # place_test_order() 
                    break # Выходим из цикла после "покупки"
                else:
                    print(f"Цена (${current_price}) выше целевой. Ждем...")
            
            # Пауза 10 секунд
            time.sleep(10)
            
        except KeyboardInterrupt:
            print("Бот остановлен вручную.")
            break
        except Exception as e:
            print(f"Произошла ошибка в цикле бота: {e}")
            time.sleep(10)

# Раскомментируйте следующую строку, чтобы запустить цикл бота
# simple_bot_logic()

Заключение и следующие шаги

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

Что дальше?

  • Обработка ошибок: Добавьте надежную обработку всех возможных ошибок API и сетевых сбоев.
  • Сложная логика: Интегрируйте технические индикаторы (RSI, Moving Averages) для принятия решений.
  • Управление состоянием: Ваш бот должен знать о своих открытых ордерах и текущих позициях.
  • WebSocket: Для высокочастотной торговли перейдите на WebSocket API для получения данных в реальном времени без задержек.

Для получения полного списка эндпоинтов и их параметров обратитесь к официальной документации API AsterDEX.