Внутрибиржевой арбитраж

Если взять 10 000 рублей, купить на них долларов, на доллары купить евро и продать евро за рубли то…. Что? А если на X рублей купить долларов, доллары обменять на франки, франки на йены, йены на евро, евро на рубли? Мама миа. Вот о чем-то этаком и поговорим.

Внутрибиржевой арбитраж

Я не знаю, когда и у кого впервые зародились такие идеи, но случилось так, что помимо обыкновенного арбитража (который зеркальные сделки на биржах) появился еще и внутрибиржевой. Раз уж есть такое разнообразие монет и мостов между ними, то теоретически возможно подловить некоторый дисбаланс в курсах и провернуть цепочки сделок так, чтобы покрыть затраты на комиссии и выйти в плюс… Подумал кто-то. А я подумал, что круто было бы проверить эту идею на практике, автоматизировать, так сказать.

Ну, и пока я проверял, за моим плечом стоял фичедемон. И каждый раз, как я добавлял какой-то функционал, фичедемон бил меня под ребро и заставлял прикрутить к скрипту еще что. А потом еще что-то. 

Меня интересовали следующие вещи:

  1. Можно ли провернуть сделки таким образом, чтобы на входе и на выходе получить одну и ту же монету, но с увеличенным балансом, при этом продавая и покупая по рынку?
  2. Почему обычно сводится к цепочке из трех сделок? Не будет ли эффективнее прокручивать цепочки из четырех, пяти сделок подряд и больше?
  3. Насколько сильно будут разниться стаканы в тот момент, когда я получу данные и тогда, когда выставлю сделку?
  4. И, наконец, если это работает, то сколько денег на этом можно заработать???!! Хотя кого я обманываю, этот вопрос был первым в списке :)

Получаем и считаем цепочки сделок

Начало

Первый алгоритм работы скрипта, с которого я начал, был прямолинеен: Скрипт получал все пары с биржи, потом по каждой паре получал значения стаканов (что бы хоть как-то уменьшить сетевые задержки, я сделал так, чтобы бот запускал 300+ параллельных запросов к бирже). После получения стаканов скрипт скакал от пары к паре, проверяя, сколько монет можно купить или продать, потратив указанное количество денег. Т.е., например, если указать, что собираемся тратить 0.005 ETH, то бот может выдать такую цепочку действий:

Расшифрую:

Шаг 1: Продать 0.005 ETH по цене 0,04176400, что позволит выручить 0.00020882 BTC

Шаг 2: Купить SALT за полученные BTC. По курсу 0,00007020 можно купить 2,97464387 монет (точнее, биржа даст купить только 2.97). На это уйдут все заработанные BTC. Точнее, почти все, с учетом подрезания биржей.

Шаг 3. Итак, мы купили 2,97464387 SALT, теперь нужно их продать за эфиры, что бы выйти в плюс. Продаем по курсу 0,00169000, и получаем 0,0050193 ETH (по расчету должны были получить 0,00502715, но из-за округлений вышло чуть меньше. Все равно, неплохо).

Нужно упомянуть, что скрипт делает расчет без учета комиссии - а на сегодняшний день на бинансе она 0.075%. Таким образом, для того, что бы получать прибыль нужно совершать сделки, которые принесут больше, чем 0.075 * 3 процентов. В примере выше это соблюдается, но это, честно говоря, редкий случай.

Скрипт сам решает, где нужно продать а где купить, пробует те или иные комбинации и выводит самую прибыльную цепочку действий (можно выводить все, ниже покажу как). Вот еще примерчик, с выгодными и невыгодными парами.

Продолжение


Реклама:


На этом этапе фичедемон схватил меня за плечи, начал трясти и требовать сделать так, что бы можно было проверять цепочки разной длины, и я был вынужден согласиться :) Получилось как то так:

BTC (длина цепи – 4 шага):

BNB (длина цепи – 5 шагов)

USDT (длина цепи – 6 шагов, 100 USDT)

Ну и так далее – чем дальше, тем медленнее, 6 шагов устанешь ждать.

Ускорение сокетами

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

  1. Получает все пары с биржи
  2. Получает все стаканы с биржи по всем полученным парам
  3. Подписывается на веб-сокеты по всем парам
  4. Каждый раз, когда происходит обновление стакана любой пары на бирже, бот обновляет локальные стаканы
  5. В отдельном потоке крутится расчет цепочек, каждый раз берет локальные стаканы, которые обновляются через сокеты в соседних потоках.

 

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

Зато обратите внимание на время слева – никаких практически задержек.

Разглагольствования:

В общем, я экспериментировал еще с другими вещами – например, сделал бота, который на основе этих данных торгует. Бот иногда торговал в плюс, иногда в минус, я не заметил каких-то позитивных вещей в его работе. Разумеется, профит был рассчитан так, что бы покрыть все комиссии со всех покупок.

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

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

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

Потом я забил на бота, упростил код и подготовил материал для статьи. Сделать так, что бы бот совершал дцать сделок в день, с каждой брал по % и богател на глазах, у меня вот так вот сходу не вышло. Может быть у вас получится?

Код

Для экспериментов вам понадобятся:

  1. Биржа Binance - 1 шт (потом сможете заменить на какую-то свою)
  2. Python 3.7+ (можно взять тут)
  3. Код, который я сложил в архив
  4. Немного свободного времени и любопытства.

Установите питон, скачайте архив, в нём найдёте файл setup.bat. Запустите его, он установит вам нужные модули питона.

Так же в архиве есть файлы simple.bat и sockets.bat.

Если запустить simple.bat, то бот отработает по первой схеме – получит пары, получит стаканы, посчитает и выдаст результат.

Если запустить sockets.bat, то бот пойдет по сложной схеме – будет обновлять стаканы через веб-сокеты, будет бесконечно просчитывать цепочки и т.п., пока его не остановите.

Все, что выводится на консоль, так же пишется в папку logs, можете если что смотреть там.

Исходные файлы там же, simple.py, sockets.py – запускаются, misc.py – всё, что связано с расчетом цепочки (там много лишнего, это с другого проекта перекочевало), custom_log.py – просто настройка логирования, вряд ли вам будет интересно что-то там править.

Теперь о настройках:

В файлах simple.py и sockets.py вы можете найти:

SUM_TO_SPEND = 0.005
SHOW_ALL_CHAINS = False
COIN_TO_INCREASE = 'BTC'
MAX_STEPS = 3

Сумму, которую вы тратите (и хотите преумножить),

Показывать ли все цепочки (если False, то только лучшую)

Монету, которую рассчитываете увеличить

Кол-во сделок в цепочке.

В общем, скачивайте, экспериментируйте, задавайте вопросы, делитесь идеями/наработками, всем процветания :)

Тэги: