Кросс-биржевой арбитраж с Python

Абстрактный

Криптовалютное пространство остается в лучшем случае слабо регулируемым и в большинстве случаев нерегулируемым, что дает участникам рынка возможность воспользоваться различными недостатками, которые все еще существуют в пространстве, даже когда криптовалютные рынки продолжают созревать и получать всеобщее признание. Таким образом, большой вопрос заключается в том, как мы, как компьютерные ученые, можем использовать эту неэффективность рынка для получения постоянной прибыли от нашего капитала, не подвергая себя значительным рискам снижения? Одним из простейших вариантов, по крайней мере концептуально, является обнаружение и исполнение арбитражных возможностей. В этой статье я определю, что такое арбитраж, исследую, как и почему они происходят, и расскажу о том, какую роль они играют в общем состоянии крипторынков. Затем я расскажу о методологии и технической реализации системы, которая может торговать такими возможностями с основным акцентом на скорость исполнения и снижение риска. Наконец, я рассмотрю свои личные экспериментальные результаты, поделюсь некоторыми фрагментами кода и расскажу о областях, где необходимы дальнейшие исследования для создания более прибыльной системы. Теперь на менее формальной ноте, давайте посмотрим, как мы можем использовать нашу системную архитектуру и навыки информатики, чтобы заработать немного денег!

Знакомство

Как определено Investopedia, «арбитраж — это одновременная покупка и продажа одного и того же актива на разных рынках с целью получения прибыли от крошечных различий в котируемой цене актива. Он использует кратковременные колебания цен на идентичные или сходные финансовые инструменты на разных рынках или в различных формах». В своих исследованиях я сосредоточусь именно на выполнении арбитражных сделок на крупных централизованных биржах, которые предлагают разработчикам доступ к API, которые можно использовать для взаимодействия с биржей.

Теперь, когда мы определили, что такое арбитраж, давайте посмотрим, почему и как они происходят. В своей статье Пауна упоминает, что отсутствие центрального органа, который мог бы обеспечить точное ценообразование, приводит к случайным колебаниям цен между различными биржами. Из того, что я видел, эти колебания обычно происходят во время значительного увеличения объема или случаев низкой ликвидности. Одним из примеров может быть крупная сделка, выполняемая на одной бирже, вызывающая резкий скачок цены. Еще одну прибыльную область для арбитражного исполнения можно найти вокруг крупных запланированных выпусков новостей, таких как протоколы ФРС. В эти периоды маркет-мейкеры склонны отключать свои алгоритмы, чтобы избежать больших просадок, вызывающих резкое снижение ликвидности рынка.

Некоторые могут задаться вопросом, есть ли какая-либо причина для проведения этих арбитражных сделок, помимо простой получения прибыли. По сути, находя и используя эти ценовые различия, алгоритм предоставляет услугу для всего рынка, сохраняя цены справедливыми и последовательными для всех участников рынка. Это связано с оговоркой, что по мере того, как все больше трейдеров стремятся использовать эти возможности, а рынки становятся более эффективными, прибыльность межбиржевой арбитражной торговли также уменьшается. Как отметил Крепелльер, «ценовые отклонения почти не существовали с апреля 2018 года», но его исследование было сосредоточено в основном на больших арбитражных возможностях, а не на небольших различиях с акцентом на скорость исполнения.

Методология

Как обсуждалось, арбитражная торговля сводится к покупке актива в одном месте по низкой цене и продаже его дорого где-то в другом месте, желательно в то же время или, по крайней мере, как можно быстрее. Но есть несколько тонкостей с практической точки зрения, которые стоит обсудить. Во-первых, мы должны посмотреть на платформы, которые мы будем использовать для совершения этих сделок. В настоящее время самыми дешевыми и наиболее точно оцененными платформами в криптографии являются крупные централизованные биржи, такие как Binance, Coinbase и Kraken. Эти биржи используют классическую модель стакана при управлении сделками. Это означает, что для каждой добавочной единицы цены, по которой актив может быть продан, биржа будет собирать предложения bid и ask от покупателей и продавцов. В нашем случае нас в первую очередь интересует верхняя часть книги заказов и мы следим за лучшими ставками и запросами. В любой момент времени совокупное количество заявок или запросов при любом заданном ценовом уровне будет иметь определенный объем, связанный с ним. Этот объем чрезвычайно важен для нас, так как арбитражная сделка, которую мы хотим выполнить, должна иметь одинаковый объем капитала для обеих сделок. Поэтому при подаче наших сделок мы можем торговать только минимумом bid и ask. Так, если биржа А имеет ставку 17000 USD (sell_i) на 1 BTC объемом 10, а биржа B имеет ask 16900 USD (buy_i) на 1 BTC с объемом 5, наша прибыль за каждую сделку (P_i) может быть выражена следующим уравнением:

Эта простая торговля также может быть сделана на крипто-крипто парах, таких как Bitcoin и Ethereum: BTCETH. Проблема с этим подходом заключается в том, что некоторые биржи будут указывать цену Ethereum в терминах Bitcoin, а некоторые будут делать обратное: например, ETHBTC. В то время как базовые активы одинаковы, наша формула должна быть скорректирована, чтобы приспособиться к переходу. Чтобы внести это изменение, мы можем переписать формулу (1) как:

Эта простая арбитражная стратегия также может быть масштабирована, чтобы привлечь больше пар активов. Например, если мы обнаружим, что в данный момент нам дешевле купить BTC за доллар США (BTCUSD), а затем конвертировать этот BTC в ETH (ETHBTC) против перехода из USD непосредственно в ETH (ETHUSD), мы можем выполнить этот треугольный арбитраж в нашу пользу. Теоретически это может быть применено к любому количеству рынков с любой стороны. Проблема с этим подходом заключается в том, что он создает гораздо больше точек отказа, если один из ордеров пропустит обнаруженную цену во время исполнения сделки. В этом случае любая неудачная сделка в общем наборе сделок приведет к эрозии прибыли и может быстро привести к убытку. И если все торгуемые активы не принадлежат трейдеру на момент исполнения, сделки должны будут выполняться последовательно, что приводит к значительному замедлению исполнения. Положительным моментом такого подхода является то, что он может быть выполнен на одной платформе, поэтому требуется только один обменный счет.

Другим важным аспектом, который следует учитывать перед настройкой арбитражного алгоритма, является определение того, какие активы будут контролироваться и торговаться. Из-за того, что криптовалютные биржи в значительной степени не регулируются, они обычно предлагают широкий спектр монет, которыми можно торговать, но одна биржа может не иметь тех же активов, что и другая биржа. Как правило, большинство бирж будут иметь BTC и ETH, но помимо этого это в основном бесплатно для всех. Кроме того, котировочные активы также могут варьироваться с некоторыми биржами, использующими USD, EUR или другую иностранную валюту, в то время как другие предпочитают использовать стабильные монеты, такие как USDC или USDT. Несмотря на то, что стейблкоины привязаны к USD, 1 USD не всегда равен 1 USDT и обменные курсы могут колебаться. Поэтому при выборе бирж, которые будут использоваться для выполнения арбитражных сделок, важно убедиться, что торгуемые активы одинаковы. Это можно сделать, запросив каждую биржу для всех пар активов, торгуемых на ней, и сгенерировав подмножество пар, которые присутствуют на каждой из них. В Binance это может быть достигнуто с помощью следующей конечной точки:

GET https://api.binance.com/api/v3/exchangeInfo

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

Прежде чем мы углубимся в реализацию алгоритма, давайте сначала рассмотрим некоторые из предварительных условий, которые нам нужно будет настроить. Как упоминалось в разделе «Методология», для выполнения кросс-биржевого арбитража нам потребуется не менее 2 торговых счетов, открытых на разных биржах. Основываясь на исследованиях, проведенных Crépellière, возможности арбитража более выражены, когда две контролируемые биржи расположены в разных странах. Однако, хотя наличие бирж в двух разных странах может быть более выгодным на бумаге, задержка увеличивается при отправке ЗАПРОСОВ API на биржи, которые находятся очень далеко от сервера, что может привести к потерям из-за медленности выполнения. Открытие счетов в разных юрисдикциях также может быть проблематичным с нормативно-правовой точки зрения. Согласно моим исследованиям, зона Goldy Locks заключается в том, чтобы открыть два счета в двух соседних или близких странах, таких как Япония и Южная Корея, и попытаться разместить сервер где-то рядом с ними обоими, чтобы минимизировать задержку.

При оценке бирж важно убедиться, что платформа является авторитетной и полностью поддерживаемой, чтобы избежать каких-либо проблем с платежеспособностью в будущем. Для максимальной скорости исполнения мы должны держать активы, находящиеся в арбитраже на биржах, поэтому любые проблемы с платежеспособностью с биржей могут привести к полной потере активов. Кроме того, крайне важно найти биржи с низкими комиссиями и торговыми сборами. Любое место ниже 0,1% комиссии было бы идеальным. Это связано с тем, что маржа прибыли каждого отдельного арбитража очень мала, и торговые сборы могут быстро съесть любую прибыль, которая генерируется алгоритмом. При реализации алгоритма нам также нужно будет убедиться, что минимальный порог прибыли больше, чем сборы, уплачиваемые за обе сделки.

Наконец, с точки зрения обмена, дополнительным бонусом является наличие фьючерсного счета, доступного трейдеру. Во время исполнения алгоритма мы вынуждены держать баланс волатильного актива, который может колебаться в цене больше, чем прибыль, которую мы получаем от арбитражных сделок. Другими словами, если BTC снизится на 5% и мы получим прибыль в размере 1% в ходе торгов, мы все равно будем получать чистый убыток без создания соответствующего механизма хеджирования. С фьючерсами мы можем открыть короткую позицию против активов, удерживаемых для устранения риска волатильности. Таким образом, если трейдер держит баланс BTC V_x на бирже X и баланс V_y на бирже Y, то V_short короткого баланса BTC должен быть:

Реализация

С нашими базами пришло время посмотреть, как этот алгоритм может быть реализован. Наша программа будет состоять из следующих уровней: облачный сервер, ценовой фид, функция обнаружения арбитража, API биржевых ордеров, уровень ведения журнала и исполнения. Мы подробно рассмотрим каждый отдельный компонент и покажем несколько примеров кода.

Облачный сервер нужен для того, чтобы увеличить скорость доступа к обменным API. Не обязательно, если пользователь находится близко к серверам обеих бирж, но мало кто имеет такую роскошь. Идеальное расположение облачного сервера должно быть как можно ближе к двум используемым биржам. Трейдеры должны запустить тест ping, чтобы сравнить доступные им варианты сервера. Для этого исследования мы использовали инстанс AWS EC2, расположенный в Токио. Экземпляр был настроен на использование Ubuntu для поддержания установки, и последний дистрибутив Python был установлен на сервере вместе со всеми библиотеками и пакетами, необходимыми для запуска алгоритма. Для получения дополнительной информации о настройке инстанса EC2 обратитесь к Документации AWS.

Наиболее важной частью алгоритма является точный и актуальный ценовой поток. Чтобы получить цену активов, подлежащих арбитражу, с каждой биржи нам нужно будет напрямую подключиться к книге заказов. Сторонний ценовой оракул не должен использоваться, так как они будут медленнее обновляться и могут привести к неточной идентификации арбитража. Трейдеры также должны избегать использования конечных точек REST API для получения данных о ценах, поскольку биржи будут налагать ограничения на скорость на количество запросов API, которые может отправлять отдельный IP-адрес. Поэтому наш ценовой поток должен быть ограничен, что приведет к прерывистому потоку. Оптимальным вариантом является использование соединения WebSocket для получения живой книги заказов для каждой биржи. Это позволит нам получать самую актуальную ценовую ленту по мере ее обновления биржей. Для Binance это может быть реализовано с помощью приведенного ниже фрагмента. Обратите внимание, что перед выполнением этого кода необходимо установить библиотеку WebSocket. Это предоставит нам лучшие ставки, аск и их соответствующие объемы.

import time, json, websocket
from datetime import datetime

ws = websocket.create_connection("wss://stream.binance.com:9443/ws")
ws.send('{"id": 1, "method": "SUBSCRIBE", "params": ["btcusdt@bookTicker"]}')

while 1:
print(json.loads(ws.recv()))

Затем нам нужно настроить функцию обнаружения арбитража. Идея проста, так как новая информация поступает из ценовой ленты, мы проверяем, если

Комиссия обозначает процентную сумму сборов берущего для обеих бирж. Это вычисление должно происходить дважды для пары бид/аск каждой биржи, как показано в (4). Лично мне нравится увеличивать плату, чтобы создать пространство для проскальзывания или позднего исполнения и по-прежнему оставаться прибыльным, если эти события произойдут. Например, если общая комиссия для обеих бирж составляет 0,2%, я обычно устанавливаю комиссию в размере 0,4%, чтобы обеспечить возможность ошибки. Как только функция возвращает true, мы должны найти максимальный объем сделки, который может быть выполнен для пары bid/ask, которая была признана прибыльной, как показано в (1). После того, как все значения собраны, функция должна вернуть результат, чтобы сделки могли быть отправлены как можно быстрее.

Чтобы отправлять сделки на биржи, мы должны сначала сгенерировать пару ключ/секрет API и хранить их в безопасности. Далее мы реализуем функционал place order, подключив API обмена и передав параметры, возвращаемые нам функцией обнаружения. В Binance мы можем подключиться к конечной точке заказа, используя приведенный ниже код. Обратите внимание, что тип сделки всегда должен быть «MARKET», так как мы хотим выполнить лучшее доступное предложение, которое существует в настоящее время. Символ ордера будет зависеть от торгуемого актива, в то время как сторона и количество будут определяться функцией обнаружения. Поскольку мы используем ордер «MARKET», нам не нужно указывать цену.

import urllib.parse
import hashlib
import hmac
import base64
import requests
import time

def get_binanceus_signature(data, secret):
postdata = urllib.parse.urlencode(data)
message = postdata.encode()
byte_key = bytes(secret, 'UTF-8')
mac = hmac.new(byte_key, message, hashlib.sha256).hexdigest()
return mac

def binanceus_request(uri_path, data, api_key, api_sec):
headers = {}
headers['X-MBX-APIKEY'] = api_key
signature = get_binanceus_signature(data, api_sec)
payload={
**data,
"signature": signature,
}
req = requests.post(("https://api.binance.us" + uri_path), headers=headers, data=payload)
return req.json()

def performTradeBinance(symbol, side, type, quantity, price, timeinforce):

api_key="api_key"
secret_key="api_secret"
uri_path = "/api/v3/order"
data = {}
if type == "MARKET":
data = {
"symbol": symbol,
"side": side,
"type": type,
"quantity": quantity,
"timestamp": int(round(time.time() * 1000))
}
else:
data = {
"symbol": symbol,
"side": side,
"type": type,
"quantity": quantity,
"price": price,
"timeInForce": timeinforce,
"timestamp": int(round(time.time() * 1000))
}
result = binanceus_request(uri_path, data, api_key, secret_key)
return result

Наконец, мы должны ввести функцию ведения журнала, которая позволит нам отслеживать прошлые показатели и анализировать, где можно внести улучшения. Самым простым и легким вариантом ведения журнала было бы вывести в текстовый файл журнала обнаруженную цену, объем, на каком обмене они произошли, а также цену, по которой ордера фактически исполнялись. Весьма вероятно, что будут небольшие различия между обнаруженными и исполненными ценами из-за высокой конкуренции со стороны других участников рынка. Эта дельта может быть уменьшена за счет увеличения скорости алгоритма и уменьшения задержки соединения. Некоторые могут предпочесть записать данные во внешнюю базу данных, но это не является обязательным требованием.

Результаты

После тестирования различных итераций этого алгоритма в течение более года очевидно, что пространство чрезвычайно конкурентоспособно и маржа прибыли может быть небольшой, если алгоритм настроен неправильно. При реализации основное внимание следует уделять скорости исполнения, так как это обеспечит основное конкурентное преимущество при торговле этим методом. Количество арбитражных возможностей также неуклонно снижается, поскольку рынки становятся более эффективными из-за усиления конкуренции.

Для этой реализации я смог достичь сквозной скорости выполнения менее 0,2 секунды, но дальнейшие улучшения могут быть сделаны с помощью более быстрого языка программирования (например, C ++) для ускорения уровня обнаружения и обработки. Потоки WebSocket также следует сделать асинхронными, а новые расположения серверов должны быть оценены для достижения дальнейшего улучшения скорости выполнения. Также важно отметить, что некоторые биржи будут торговать против своих клиентов, создавая поддельные объемы, спуфинг и другие виды манипулирования рынком, поэтому, даже когда будут обнаружены большие арбитражные возможности, трейдер не сможет фактически их выполнить. Если такие проблемы обнаружены, трейдеры должны немедленно найти другую платформу для использования. Для меня это было очевидно при торговле на FTX, и мы все знаем, чем это закончилось.

С точки зрения прибыльности, в среднем пара, такая как ETHUSD, имеет около 40 арбитражных возможностей в любой день с маржой прибыли 0,5% или более за сделку. Как правило, в периоды высокой волатильности доступно больше возможностей, поэтому крупные выпуски новостей, такие как fed Minutes, часто могут обеспечить идеальную среду для арбитражного исполнения. К сожалению, если сделка не выполняется по выгодной для нас цене, это может привести к убыткам, и не все сделки будут прибыльными. Что очень важно, так это то, что сумма всех сделок приводит к чистой прибыли, и следует ожидать случайных плохих сделок. Могут быть введены более сложные типы ордеров, такие как ордера на fill или kill limit, но это создает риск того, что одна сторона сделки не выполнит, оставив нас с несбалансированной позицией.

Заключение

В заключение, этот эксперимент оказался очень познавательным, но для тех, кто ищет денежный принтер, который можно включить и оставить для торговли, это не так. В то время как в 2022 году существует множество возможностей для арбитража, пространство становится все более конкурентоспособным и привлекает большой интерес со стороны высокочастотных торговых фирм и других институциональных игроков. Таким образом, требования к инфраструктуре для получения прибыли в будущем будут продолжать расти, а учреждения с VIP-счетами, чрезвычайно низкими торговыми сборами и колокейшн с биржами будут продолжать выбивать индивидуальных трейдеров, желающих выполнять свои собственные алгоритмы арбитража. Хотя я смог получить разумную прибыль от этого эксперимента, я столкнулся с уменьшающейся отдачей. В то время как централизованное биржевое пространство становится все более переполненным, существует гораздо больше возможностей арбитража в децентрализованном финансовом пространстве (DeFi) и на децентрализованных биржах (DEX), таких как Uniswap, SushiSwap и многих других. Таким образом, индивидуальные трейдеры должны уделять пристальное внимание новым технологиям и рынкам, чтобы находить новые возможности по мере их возникновения.

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

Источники:

1 Арбитраж на рынке криптовалют, 2022, Томми Крепелльер, Маттиас Пельстер и Штефан Цейсбергер

2 Арбитражные торговые системы для криптовалют. Принципы проектирования и серверная архитектура, 2018, Cristian PĂUNA

3 Арбитраж: как арбитраж работает в инвестировании, с примерами, 2022, Джейсон Фернандо, https://www.investopedia.com/terms/a/arbitrage.asp

4 Документация по API Binance, https://binance-docs.github.io/apidocs/spot/en/#introduction

5 Документация по AWS EC2, https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html

Источник