Если взять 10 000 рублей, купить на них долларов, на доллары купить евро и продать евро за рубли то…. Что? А если на X рублей купить долларов, доллары обменять на франки, франки на йены, йены на евро, евро на рубли? Мама миа. Вот о чем-то этаком и поговорим.
Внутрибиржевой арбитраж
Я не знаю, когда и у кого впервые зародились такие идеи, но случилось так, что помимо обыкновенного арбитража (который зеркальные сделки на биржах) появился еще и внутрибиржевой. Раз уж есть такое разнообразие монет и мостов между ними, то теоретически возможно подловить некоторый дисбаланс в курсах и провернуть цепочки сделок так, чтобы покрыть затраты на комиссии и выйти в плюс… Подумал кто-то. А я подумал, что круто было бы проверить эту идею на практике, автоматизировать, так сказать.
Ну, и пока я проверял, за моим плечом стоял фичедемон. И каждый раз, как я добавлял какой-то функционал, фичедемон бил меня под ребро и заставлял прикрутить к скрипту еще что. А потом еще что-то.
Меня интересовали следующие вещи:
- Можно ли провернуть сделки таким образом, чтобы на входе и на выходе получить одну и ту же монету, но с увеличенным балансом, при этом продавая и покупая по рынку?
- Почему обычно сводится к цепочке из трех сделок? Не будет ли эффективнее прокручивать цепочки из четырех, пяти сделок подряд и больше?
- Насколько сильно будут разниться стаканы в тот момент, когда я получу данные и тогда, когда выставлю сделку?
- И, наконец, если это работает, то сколько денег на этом можно заработать???!! Хотя кого я обманываю, этот вопрос был первым в списке :)
Получаем и считаем цепочки сделок
Начало
Первый алгоритм работы скрипта, с которого я начал, был прямолинеен: Скрипт получал все пары с биржи, потом по каждой паре получал значения стаканов (что бы хоть как-то уменьшить сетевые задержки, я сделал так, чтобы бот запускал 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 шагов устанешь ждать.
Ускорение сокетами
Эта идея лежала на поверхности, и фичедемон, угрожая палкой, заставил воплотить её в жизнь. Система работы поменялась, хотя общие принципы остались. Теперь скрипт действует так:
- Получает все пары с биржи
- Получает все стаканы с биржи по всем полученным парам
- Подписывается на веб-сокеты по всем парам
- Каждый раз, когда происходит обновление стакана любой пары на бирже, бот обновляет локальные стаканы
- В отдельном потоке крутится расчет цепочек, каждый раз берет локальные стаканы, которые обновляются через сокеты в соседних потоках.
Получилось реально быстро – и печально, т.к. я не ни разу не увидел достойной сделки, все в минус.
Зато обратите внимание на время слева – никаких практически задержек.
Разглагольствования:
В общем, я экспериментировал еще с другими вещами – например, сделал бота, который на основе этих данных торгует. Бот иногда торговал в плюс, иногда в минус, я не заметил каких-то позитивных вещей в его работе. Разумеется, профит был рассчитан так, что бы покрыть все комиссии со всех покупок.
Потом я добавил логику, что бы перед выставлением ордеров бот брал самые актуальные курсы – ничего полезного, только замедление работы.
Позже я его изменил, что бы он селлы делал по рынку, а баи по рассчитанному ранее курсу.
Потом поменял, что бы последний ордер бот выставлял так, что бы гарантированно получать больше, чем потратил изначально – и ордера стали висеть по несколько часов.
Потом я забил на бота, упростил код и подготовил материал для статьи. Сделать так, что бы бот совершал дцать сделок в день, с каждой брал по % и богател на глазах, у меня вот так вот сходу не вышло. Может быть у вас получится?
Код
Для экспериментов вам понадобятся:
- Биржа Binance - 1 шт (потом сможете заменить на какую-то свою)
- Python 3.7+ (можно взять тут)
- Код, который я сложил в архив
- Немного свободного времени и любопытства.
Установите питон, скачайте архив, в нём найдёте файл 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, то только лучшую)
Монету, которую рассчитываете увеличить
Кол-во сделок в цепочке.
В общем, скачивайте, экспериментируйте, задавайте вопросы, делитесь идеями/наработками, всем процветания :)
UPD: Читайте продолжение статьи тут :)
Результат идентичный.
Изначально я даже не стал торговать и вместо выставления сделок я просто записывал результат и теоретический процент в текстовый файл.
Разница в том что я модифицировал стандартную либу бинанса таким образом чтобы открыть один вебсокет сразу на несколько пар.
Таким образом открыв 4 вебсокета для разных абсолютно всех пар бинанса. (первый сокет для всек пар торгующихся к битку, второй для всех пар торгующихся к эфиру и треттий для BNB и четвертый для USDT) я получил все возможные вариаты обмена.
Для себя я сразу понял что чем меньше шагов тем лучше и использовал только обмен в 3 этапа.
Направление обмена и конечная валюта в которой рассчитывалась прибыль не играло роли(пробовал все 12 направлений обмена).
Пример одного из этих направлений.
Изначально имеем биток.
1 действие покупаем альт за usdt (на определённую сумму к примеру на 100$).
2 действие продаём альт за эфир.
3 действие продаём эфир за usdt.
Изначально в формулу уже был заложен процент на комиссию.
Запустил бота.
И ушел спать.
Утром открыл файл в который записывался теоретический результат и чуть не упал со стула)))
Теоретический процент за ночь перевалил за 1000%
Но сразу внутреннее чутьё забило тревогу.
Что то тут не так.
Процент слишком большой.
Начал проверять и в ручную пересчитывать все значения.
Действительно теоретический процент по каждой сделке был верен но я не проверял абсолютно все селки я рандомно проверил штук 40 из почти 2000 и они все были верны.
Я был доволен)))
НО это было только начало)
Далее я сэмулировал выставление ордеров.
Но ордера как многое знают выставляются уже не с помощью вебсокета а с помощю рест запроса.
Примерно прикинув что средний пинг с арендованного мною сервака до бинанса составляет 100ms.
Выставил задержку 100ms и через после отправил рест запрос но не на сделку а на получение стакана той пары (ALT-USDT) с которой начинался цикл.
После получения ответа я отправлял второй рест на стакан по той паре за которую продавал.(ALT-ETH)
И после ответа делал третий запрос уже на пару (ETH-USDT)
И получив все эти данные провёл повторный пересчет.
И выяснилось что за эти доли секунды цены уже поменялись и если бы я открыл эту сделку то продался бы в минус.
Начал внимательно смотреть за стаканами.
И заметил что в доли секунды теоретически прибыльная сделка превраается в убыточную.
Добавил дополнительные логеры.
И увидел следующую картину в течении примерно 10-50ms пара по которой должна была происходить продажа (ALT-ETH) альта резко просаживалась в цене.
Попробовал найти сервак с меньшим пингом до бинанса.
Нашёл, пинг был около 10-40ms
Повторил эксперимент.
Результат тот же.
Далее изменил Алгоритм таким образом чтобы все 3 рест запроса на проверку отправлялись одновременно и без задержек.
(Эмитирую ситуацию когда на аккаунте имеются все 3 валюты и одновременно продаются)
Результат снова не изменился.
За время что проходило с момента обнаружения сигнала до того как биржа ответит на запрос по ресту цена резко проваливалась.
Это подтолкнуло меня к выводу что это не боты конкурентов такие шустрые.
Это сама биржа рубит бабло на этом)
Есть мысля только вот не смогу я это сам реализовать - не программист я...
Логику могу на почту закинуть... Думаю она сработает в плюс в большинстве случаев....
Господа, а если это делать вручную (боюсь ставить бота из-за вероятности бана), то по какому алгоритму?
Объясните, пожалуйста.
В любой связке и последовательности валют, просто понять, по какому принципу отбирать и выстраивать цепочку пар?
Пробовала выстраивать эту репку с текущим процентным увеличением цены + закладывание комиссии в стоимость, фигня какая-то получилась, в минус ушла.
Иными словами, каков принцип отбора пар и как это высчитать, будет плюс в конце цепочки или нет? На что обращать внимание?
Если упрощенно
Вы начинаете с X монет, нужно сделать так, что бы по итогам последней сделки было X + профит монет.
При этом на каждой промежуточной сделке теряется комиссия (3 списания как минимум)
Т.е. вы берете X монет, покупаете на X монет Y других монет по текущему курсу (но на баланс падает Y-fee%), потом на Y-fee% покупаете Z монет, на баланс падает Z-fee%, если этот Z-fee% продать по текущей цене за X, и если X-fee% больше либо равен изначального то это профитная сделка.
Делаете так для каждой пары, и выбираете самую профитную (но это редкий случай, обычно они все в небольшой минус, т.к. уже много ботов, которые кормятся по этому алгоритму)
Да, видимо, я неверно считала.
Какие криптовалютные пары для такой цепочки предпочтительней выбирать? Или это вообще не имеет значения?
Если не имеет, то, может, есть какая-то формула, по которой сразу можно определить, что на данный момент именно эта пара принесёт профит?
То есть, как ориентироваться, не просчитывать же каждый вариант?
Там не так много комбинаций, если на то пошло, да и формулу все равно придется для каждой строки применять, т.к. курсы мало того что расходятся, так еще и расходятся именно в тот момент, когда вы их считаете..
То есть, как именно нужно её выстраивать изначально?
Если взять любую цепочку, то скорее всего она будет убыточна на размер цепочки * размер комиссии, потому что круглосуточно мониторится и корректируется ботами.
Поэтому реальный шанс получить прибыль, это момент резкого роста или проседания, включая пампы. Еще полезными могут оказаться пары, которые только что добавили на биржу или наоборот, собираются убрать из листинга. Возможно пары, по которым намечается инфоповод типа хардфорка или взлома. В общем, нужны пары, которые способны резко изменить курс, с сопровождающим большим объемом - таким, который текущие боты не способны за раз переварить.
Я лично нахожу более правильным мониторить всё, что бы ничего не пропустить, но у меня есть возможность использовать виртуальные сервера в нужном количестве, если хотите заранее оценивать, следите за твиттером, реддитом и т.п., это в любом случае правильно