ccxt на Python необходимо использовать методы exchange.fetch_trading_fees() (для комиссий по символам) или exchange.fetch_fees() (для глобальных комиссий). Полученные данные содержат текущие ставки maker и taker, которые зависят от вашего торгового объема или баланса на бирже. Важно учитывать, что структура ответа может отличаться для разных бирж.Исходный код
Точный расчет комиссий мейкера и тейкера является критически важным аспектом в алготрейдинге, особенно при разработке стратегий, таких как треугольный арбитраж на OKX, где даже небольшие расхождения могут привести к убыткам. Биржи часто используют многоуровневую систему комиссий (Fee Tiers), которая зависит от вашего торгового объема за определенный период или от размера вашего баланса в нативных токенах биржи. ccxt предоставляет удобные методы для получения этой информации.
Ниже представлен Python-скрипт, который демонстрирует, как получить текущие комиссии мейкера и тейкера для заданной биржи и торгового символа. Скрипт пытается сначала использовать fetch_trading_fees() для получения комиссий по конкретному символу, а затем, в случае неудачи или отсутствия символа, переключается на fetch_fees() для получения глобальных комиссий аккаунта.
import ccxt
import os
def get_current_fees(exchange_id: str, symbol: str = None) -> dict:
"""
Получает текущие комиссии мейкера и тейкера для указанной биржи и символа.
Args:
exchange_id (str): ID биржи (например, 'binance', 'okx').
symbol (str, optional): Торговый символ (например, 'BTC/USDT').
Если None, попытается получить глобальные комиссии.
Returns:
dict: Словарь с комиссиями 'maker' и 'taker', или пустой словарь в случае ошибки.
"""
try:
exchange_class = getattr(ccxt, exchange_id)
exchange = exchange_class({
'apiKey': os.environ.get(f'{exchange_id.upper()}_API_KEY'),
'secret': os.environ.get(f'{exchange_id.upper()}_SECRET'),
'password': os.environ.get(f'{exchange_id.upper()}_PASSWORD', ''), # Для OKX и некоторых других
'enableRateLimit': True,
'options': {
'defaultType': 'spot', # Или 'future', 'margin' в зависимости от нужд
}
})
# Загружаем рынки, это часто необходимо для корректной работы с символами
exchange.load_markets()
maker_fee = None
taker_fee = None
# 1. Попытка получить комиссии по символу (предпочтительный метод)
if symbol and exchange.has['fetchTradingFees']:
try:
trading_fees = exchange.fetch_trading_fees()
if symbol in trading_fees:
maker_fee = trading_fees[symbol]['maker']
taker_fee = trading_fees[symbol]['taker']
print(f"Комиссии для {symbol} (через fetch_trading_fees): Maker={maker_fee}, Taker={taker_fee}")
return {'maker': maker_fee, 'taker': taker_fee}
else:
print(f"Символ {symbol} не найден в fetch_trading_fees. Попытка получить глобальные.")
except Exception as e:
print(f"Ошибка при получении fetch_trading_fees для {symbol}: {e}. Попытка получить глобальные.")
# 2. Попытка получить глобальные комиссии
if exchange.has['fetchFees']:
try:
global_fees = exchange.fetch_fees()
# Структура global_fees может сильно отличаться.
# Обычно ищем 'trading' -> 'maker'/'taker' или 'info'
if 'trading' in global_fees and 'maker' in global_fees['trading'] and 'taker' in global_fees['trading']:
maker_fee = global_fees['trading']['maker']
taker_fee = global_fees['trading']['taker']
print(f"Глобальные комиссии (через fetch_fees): Maker={maker_fee}, Taker={taker_fee}")
return {'maker': maker_fee, 'taker': taker_fee}
elif 'info' in global_fees:
# Некоторые биржи возвращают сырые данные в 'info',
# которые нужно парсить вручную. Это сильно зависит от биржи.
# Пример для OKX: комиссии могут быть в 'info' -> 'data' -> [0] -> 'makerFeeRate'
if exchange_id == 'okx' and 'data' in global_fees['info'] and len(global_fees['info']['data']) > 0:
data = global_fees['info']['data'][0]
maker_fee = float(data.get('makerFeeRate', 0))
taker_fee = float(data.get('takerFeeRate', 0))
print(f"Глобальные комиссии OKX (через fetch_fees['info']): Maker={maker_fee}, Taker={taker_fee}")
return {'maker': maker_fee, 'taker': taker_fee}
else:
print(f"Не удалось найти maker/taker комиссии в fetch_fees для {exchange_id}.")
except Exception as e:
print(f"Ошибка при получении fetch_fees для {exchange_id}: {e}")
if maker_fee is None or taker_fee is None:
print(f"Не удалось получить комиссии для {exchange_id} (символ: {symbol}).")
print("Пожалуйста, проверьте документацию биржи и структуру ответа CCXT.")
print("Возможно, вам потребуется вручную парсить 'info' поле или использовать другой метод.")
return {'maker': maker_fee, 'taker': taker_fee}
except AttributeError:
print(f"Биржа с ID '{exchange_id}' не найдена в CCXT.")
return {}
except Exception as e:
print(f"Произошла непредвиденная ошибка: {e}")
return {}
if __name__ == "__main__":
# Установите свои API ключи как переменные окружения
# Например, в терминале:
# export BINANCE_API_KEY='YOUR_BINANCE_API_KEY'
# export BINANCE_SECRET='YOUR_BINANCE_SECRET'
# export OKX_API_KEY='YOUR_OKX_API_KEY'
# export OKX_SECRET='YOUR_OKX_SECRET'
# export OKX_PASSWORD='YOUR_OKX_PASSWORD' # Для OKX требуется пароль
print("--- Тест для Binance ---")
binance_fees = get_current_fees('binance', 'BTC/USDT')
if binance_fees and binance_fees['maker'] is not None:
print(f"Итоговые комиссии Binance для BTC/USDT: Maker={binance_fees['maker']}, Taker={binance_fees['taker']}")
else:
print("Не удалось получить комиссии для Binance.")
print("\n--- Тест для OKX ---")
# OKX часто возвращает глобальные комиссии через fetch_fees, даже если запрошен символ.
# Для OKX также важно указать 'password' в настройках биржи.
okx_fees = get_current_fees('okx', 'ETH/USDT')
if okx_fees and okx_fees['maker'] is not None:
print(f"Итоговые комиссии OKX для ETH/USDT: Maker={okx_fees['maker']}, Taker={okx_fees['taker']}")
else:
print("Не удалось получить комиссии для OKX.")
print("\n--- Тест для несуществующей биржи ---")
non_existent_fees = get_current_fees('nonexistentexchange', 'BTC/USDT')
if not non_existent_fees:
print("Корректно обработана несуществующая биржа.")
Разбор параметров
exchange_id: Строковый идентификатор биржи, поддерживаемойccxt(например,'binance','okx','bybit'). Используется для динамического создания экземпляра класса биржи.symbol: Строковый идентификатор торговой пары (например,'BTC/USDT','ETH/USDT'). Этот параметр является необязательным. Если он указан, скрипт сначала попытается получить комиссии, специфичные для этой пары. Если не указан, или если специфичные комиссии недоступны, скрипт попытается получить глобальные комиссии аккаунта.exchange.has['fetchTradingFees']: Флаг, указывающий, поддерживает ли биржа методfetch_trading_fees(), который обычно возвращает комиссии для каждой торговой пары. Это предпочтительный метод, так как комиссии могут различаться для разных инструментов.exchange.has['fetchFees']: Флаг, указывающий, поддерживает ли биржа методfetch_fees(), который обычно возвращает глобальные комиссии аккаунта. Структура данных, возвращаемых этим методом, может сильно варьироваться между биржами, особенно поле'info', которое содержит сырые данные от API биржи. В некоторых случаях, как при создании кастомного адаптера CCXT.Pro, может потребоваться ручной парсинг этих данных.maker: Комиссия, взимаемая за лимитные ордера, которые добавляют ликвидность в стакан ордеров. Обычно она ниже комиссии тейкера или даже может быть отрицательной (rebate).taker: Комиссия, взимаемая за рыночные ордера или лимитные ордера, которые немедленно исполняются, забирая ликвидность из стакана ордеров.- Переменные окружения: Для безопасного хранения API-ключей и секретов рекомендуется использовать переменные окружения (
os.environ.get()). Это предотвращает жесткое кодирование конфиденциальной информации в коде.
Как запустить
Для запуска скрипта выполните следующие шаги:
-
Установите
ccxt: Если у вас еще не установленccxt, установите его с помощью pip:pip install ccxt -
Настройте API-ключи: Экспортируйте свои API-ключи и секреты как переменные окружения. Замените
YOUR_BINANCE_API_KEY,YOUR_BINANCE_SECRETи т.д. на ваши реальные ключи. Для OKX также потребуетсяPASSWORD(торговый пароль).export BINANCE_API_KEY='YOUR_BINANCE_API_KEY' export BINANCE_SECRET='YOUR_BINANCE_SECRET' export OKX_API_KEY='YOUR_OKX_API_KEY' export OKX_SECRET='YOUR_OKX_SECRET' export OKX_PASSWORD='YOUR_OKX_PASSWORD' # Для других бирж аналогично: EXCHANGENAME_API_KEY, EXCHANGENAME_SECRETВ Windows вы можете использовать
setвместоexportили настроить переменные окружения через системные настройки. -
Сохраните скрипт: Сохраните предоставленный Python-код в файл, например,
get_fees.py. -
Запустите скрипт: Откройте терминал или командную строку, перейдите в директорию, где вы сохранили файл, и выполните:
python get_fees.py
Скрипт выведет текущие комиссии для Binance и OKX (если ключи настроены) и продемонстрирует обработку ошибок для несуществующей биржи. Помните, что для оптимизации производительности и снижения нагрузки на API, особенно при работе с большим объемом данных, можно рассмотреть интеграцию Redis для кэширования часто запрашиваемых данных, таких как комиссии, если они не меняются слишком часто.




