Создание клиента API Kraken с помощью PHP8 (2/2)

Добро пожаловать во вторую и последнюю часть этого поста, первую часть вы можете найти здесь, в первой части мы объяснили использование REST API Kraken.

В этой части мы добавим поддержку WebSocket в наш клиент, так как Kraken API позволяет нам получать данные и выполнять действия в реальном времени, используя протокол WebSocket.

Эта вторая часть не посвящена тому, как создать WebSocket-клиент, ее цель — рассказать об использовании Kraken WebSocket с помощью PHP8 и отличной клиентской библиотеки Ratchet, она же Pawl.

Официальную документацию Kraken WebSocket API можно найти здесь.

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

Публичный доступ

Давайте рассмотрим один из самых основных вариантов использования этого WebSocket API — получение цен в виде свечей. Для этого мы подключимся к ws.kraken.com, используя протокол wss://.

После подключения мы подпишемся на получение «ohlc» AKA цены открытия high low close и других данных, связанных с объемом, полезных для построения сообщения, связанного со свечой, для символа пары BTC/EUR с интервалом в одну минуту, меньшим интервала для такого рода сообщений.

Чтобы охватить все возможности использования публичного/частного API WebSocket, нам нужно только добавить новый метод для отправки запроса и потока данных. Поскольку код, который мы написали в первой части, уже позволяет получать токены аутентификации WebSocket, используя специальную конечную точку REST API.

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

Поэтому давайте добавим некоторые конфигурации, связанные с WebSocket, в наш клиент, а затем новый метод stream(), который может это сделать.

Использование WebSocket-клиента Ratchet

Мы не будем разрабатывать WebSocket-клиент для этого, а просто добавим клиент Ratchet версии 0.4 AKA Pawn в качестве зависимости нашего клиента, используя composer.

composer require ratchet/pawn@0.4

Вход в полноэкранный режим Выйти из полноэкранного режима

Затем нам нужно добавить две новые константы в наш клиентский класс, содержащие публичные и приватные конечные точки WebSocket.

class KrakenAPIClient
{
// ...
    public const WEBSOCKET_PUBLIC_ENDPOINT = 'ws.kraken.com';
    public const WEBSOCKET_PRIVATE_ENDPOINT = 'ws-auth.kraken.com';
// ...
Войти в полноэкранный режим Выйти из полноэкранного режима

Метод stream()

Затем наш новый метод «stream», подпись этого метода содержит вызываемую функцию и необходимую конечную точку. Этот метод просто подключается и передает метод обратного вызова.

Если при подключении произойдет что-то не так, этот метод выбросит KrakenApiException, содержащий ошибку(и).

public function stream(callable $callback, string $endpoint = self::WEBSOCKET_PUBLIC_ENDPOINT): void
{
    RatchetClientconnect(sprintf('wss://%s', $endpoint))->then(
        $callback,
        function ($e) {
            throw new KrakenAPIException(
                sprintf('Error while connecting to Kraken API WebSocket: "%s".', $e->getMessage())
            );
        }
    );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Вот и все, друзья. Теперь мы рассмотрим, как его использовать, в частности, как кодировать вызываемый параметр обратного вызова и взаимодействовать с потоком сообщений WebSocket.

Как использовать

Обратите внимание, что приведенный ниже код — это вырванный из контекста пример из другого проекта, использующего этот клиент.

use NicolasBonniciPhpKrakenApiClientKrakenAPIClient;
use RatchetClientWebSocket;

$client = new KrakenAPIClient();

$client->stream(function (WebSocket $conn) use ($markets, $interval) {
    $conn->send(
        json_encode([
            'event' => self::WS_SUBSCRIBE,
            'pair' => array_keys($markets),
            'subscription' => [
                'interval' => $interval,
                'name' => self::WS_MESSAGE_CANDLE
            ]
        ])
    );

    $conn->on('message', function ($msg) use ($conn, $markets, $interval) {
        $this->logger->info(sprintf('New message received: "%s".', $msg));
        $event = json_decode($msg);

        if (false === is_array($event)) {
            return;
        }

        if ($event[self::WS_MESSAGE_CANDLE_KEY_EVENT_TYPE] === sprintf('%s-%s', self::WS_MESSAGE_CANDLE, $interval)) {
            $symbol = $event[self::WS_MESSAGE_CANDLE_KEY_SYMBOL];
            $candle = $event[self::WS_MESSAGE_CANDLE_KEY_DATA];

            // Do something with the $candle data
        }
    });

    $conn->on('close', function ($msg) use ($conn) {
        $this->logger->info(sprintf('[%s] WebSocket stream closed: "%s".', self::class, $msg));
    });
});
Вход в полноэкранный режим Выход из полноэкранного режима

В данном примере кода первый параметр $callback KrakenAPIClient::stream() получает один экземпляр RatchetClientWebSocket в качестве аргумента $conn.

Используя этот аргумент, вы можете взаимодействовать с одним или несколькими потоками, отправлять запросы или прослушивать сообщения в реальном времени. Вы также можете получить доступ к некоторым событиям жизненного цикла соединения WebSocket.

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

Частный доступ

На этом уровне нет необходимости больше редактировать код нашего клиента, он уже готов к отправке после упаковки с помощью composer и packagist.

Сначала давайте воспользуемся настоящим клиентом для получения токена аутентификации WebSocket из Kraken Rest API.

$client = new KrakenAPIClient('YOUR API KEY', 'YOUR API SECRET');

$response = $client->query('private/GetWebSocketsToken');
Вход в полноэкранный режим Выход из полноэкранного режима

На этом уровне, если все прошло гладко, ответ содержит ключ «token», который нам нужно будет отправить в полезной нагрузке нашего WebSocket-запроса позже.

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

$client->stream(function (WebSocket $conn) {
    $conn->send(
        json_encode([
            'event' => self::WS_SUBSCRIBE,
            'subscription' => [
                'name' => self::WS_MESSAGE_OWN_TRADES,
                'token' => 'YOUR TOKEN',
            ],
        ])
    );

    $conn->on('message', function ($msg) {

        $this->logger->info(sprintf('New message received: "%s".', $msg));
        $event = json_decode($msg);

        if (false === is_array($event)) {
            return;
        }

        var_dump($event);
    });

    $conn->on('close', function ($msg) {
        $this->logger->info(sprintf('[%s] WebSocket stream closed: "%s".', self::class, $msg));
    });
},
    KrakenAPIClient::WEBSOCKET_PRIVATE_ENDPOINT
);

Вход в полноэкранный режим Выход из полноэкранного режима

Запустив этот код в контексте CLI, вы увидите активность ваших сделок в реальном времени, в противном случае используйте ping-запросы для поддержания соединения с потоком WebSocket.

Хотите больше?

Окончательный код клиента размещен и поддерживается на этом репозитории Gitlab, не стесняйтесь использовать его в своих проектах, связанных с криптовалютами, и, конечно, вносите свой вклад.

Спасибо, что прочитали эту статью из двух частей о том, как создать клиент Kraken API на PHP 8.

Оцените статью
Procodings.ru
Добавить комментарий