Любой торговой системе нужно одно число, прежде чем она примет хоть какое-то решение: комиссия вашего счёта. Сетка обязана знать, перекрывает ли её шаг круг. Арбитраж ставки финансирования — окупается ли перенос на двух ногах. Маркет-мейкер — где его котировка перестаёт иметь смысл.
18 сентября 2026 года мы замерили, откуда это число берётся на самом деле, — прибором только на чтение, по живым счетам. На двух площадках из трёх оно приходит не от биржи.
Что мы мерили
Прибор задаёт два вопроса в одном прогоне:
- что сообщает описание рынка в клиентской библиотеке, и
- что отвечает `fetchTradingFee` для каждого подключённого счёта.
Библиотека: ccxt 4.5.52. Площадки: Binance, Bybit, OKX. Инструмент: BTC/USDT, спот и перпетуал.
Находка 1: ни одна из трёх площадок не называет ставку в описании рынка
У любой торговой библиотеки есть поля market.maker и market.taker. В них всегда лежит число, и поэтому они выглядят как ответ биржи. Это не он.
В ccxt 4.5.52 спотовым рынкам Bybit литерал 0.001 / 0.001 записывается напрямую (bybit.js:1881). Контрактам достаётся safeNumber(market, 'takerFee', 0.0006) — значение по умолчанию, которое применяется всегда, когда публичный эндпоинт инструментов не несёт поля комиссии, а он его не несёт. У OKX то же самое из собственного блока умолчаний (okx.js:665-678).
Мы проверили сырой ответ площадки за каждой из шести строк. Ни одна из трёх площадок не объявляет ставку maker/taker в описании рынка. Все шесть чисел были умолчаниями библиотеки.
Это не изъян библиотеки: описание рынка не является утверждением о вашем счёте и никогда им не задумывалось. Изъян — в том, чтобы читать его как утверждение.
Находка 2: наш счёт на Bybit платит примерно втрое больше числа из библиотеки
| умолчание библиотеки | наш счёт (fetchTradingFee) | |
|---|---|---|
| Bybit перпетуал | maker 0,0100 % · taker 0,0600 % | maker 0,0360 % · taker 0,1000 % |
| Bybit спот | maker 0,1000 % · taker 0,1000 % | maker 0,1000 % · taker 0,1800 % |
| Binance перпетуал | maker 0,0200 % · taker 0,0500 % | maker 0,0200 % · taker 0,0500 % |
| Binance спот | maker 0,1000 % · taker 0,1000 % | maker 0,1000 % · taker 0,1000 % |
На перпетуалах Bybit мейкерская ставка нашего счёта — в 3,6 раза выше умолчания, тейкерская — в 1,67 раза. Это не ошибка чтения на стороне API: 24 августа 2026 года мы сверили её с фактическими списаниями — лимитный вход стоил 0,00116356 при нотионале 3,2321 (0,036 %), рыночный ордер — 0,00333615 при 3,3361 (0,100 %).
Находка 3: число библиотеки отстаёт и от собственной опубликованной таблицы площадки
Опубликованная страница комиссий Bybit (обновлена 2 сентября 2026) указывает для не-VIP перпетуалов maker 0,02 % / taker 0,055 %. Умолчание библиотеки — 0,01 % / 0,06 %. То есть в игре три разных числа: умолчание библиотеки, опубликованная таблица площадки и то, что реально списывают со счёта, — и они друг с другом не согласны.
Почему это тихо ломает софт
Большинство систем разрешают ставку лестницей, которая читается как очевидно правильная:
ставка счёта (fetchTradingFee) → описание рынка → консервативный фолбэкПоследняя ступень не выполняется никогда. market.taker всегда больше нуля, поэтому условие перехода к фолбэку не срабатывает ни разу. Какое бы аккуратное число вы ни положили в основание этой лестницы, оно — мёртвый код.
Мы нашли это у себя, и цена оказалась измеримой. Наш фолбэк для перпетуалов был поднят в августе до 0,036 % / 0,10 % именно потому, что замер показал занижение круга до 3,6 раза. Он не применился ни разу. Перепись машиной нашла 18 мест, читающих ставку, против шести, которые дал ручной поиск. Среди них:
- •Арбитраж фандинга считал круг двух ног как 0,10 % + 0,06 % вместо 0,15 % + 0,10 %. Точка безубытка выходила 0,020 % вместо 0,031 % — то есть ставка фандинга 0,025 % за 8 часов проходила гейт входа и круг не покрывала.
- •Межбиржевой арбитраж держал там же собственный, отдельный литерал фолбэка — ниже замеренного спотового тейкера, из-за чего чистый эдж завышался на 0,10 % за круг.
- •Карточка биржи в интерфейсе показывала умолчание библиотеки пользователю как «комиссию вашего счёта».
Как проверить это у себя
Три строки, на вашем собственном ключе:
const market = exchange.markets['BTC/USDT:USDT'];
console.log(market.taker, market.maker); // что говорит библиотека
console.log(await exchange.fetchTradingFee('BTC/USDT:USDT')); // что платит ваш счётИ вопрос, который стоит задать собственному коду: когда ставка счёта недоступна, ваш фолбэк действительно срабатывает — или его закрывает поле, которое никогда не бывает пустым?
Границы этого замера
Назовём их прямо, потому что замер без границ — это не замер, а заявление:
- •Три площадки, наши счета. Это не обзор рынка. Ваши ставки отличаются VIP-уровнем, регионом и настройками оплаты комиссии токеном.
- •Строка OKX — счёт testnet. Ставки боевого счёта OKX здесь не замерены.
- •Спотовый тейкер Bybit 0,18 % стоит на одном источнике — эндпоинте счёта. Он не подтверждён ни одной найденной нами опубликованной таблицей Bybit, и мы ещё не сверили его с фактическими спотовыми списаниями. При этом у Bybit есть региональные варианты с асимметричной спотовой схемой (европейское юрлицо публикует maker 0,1 % / taker 0,25 %) — та же форма, другая величина.
- •Опубликованные ставки Binance в этом замере не запрашивались: числа счёта и библиотеки совпали, спорить было не о чем.
Что мы изменили у себя
У вопроса «какая ставка» теперь есть владелец, который сначала отвечает на другой вопрос: назвала ли её площадка вообще. Он читает сырой ответ площадки, а не нормализованное поле, и отвечает «не названа» третьим ответом — не нулём и не умолчанием, выданным за ответ биржи. Там, где площадка молчит, применяется замеренный консервативный фолбэк — ровно то, ради чего он и замерялся.