API Binance, KuCoin и Huobi на C# – WebSocket

Продолжим обсуждать использование C#-обёртки для API криптовалютных бирж от JKorf.
Эти ребята разработали C#-обёртки уже для API 11 криптобирж:
  1. Binance.Net
  2. Kucoin.Net
  3. Huobi.Net
  4. Bitfinex.Net
  5. Bybit.Net
  6. Bittrex.Net
  7. Kraken.Net
  8. FTX.Net
  9. CoinEx.Net
  10. Zapper.Net

При работе с данными биржи некоторые задачи требуют получения информации в реальном времени. Если вы хотите показывать текущие котировки, то, конечно, можно с какой-то частотой дёргать соответствующий метод REST API и получать последнюю цену. Следить за статусами своих ордеров, например, тоже можно с периодичность раз в минуту. Но что, если вам надо моментально среагировать на событие исполнения заявки и нельзя опоздать ни на секунду? Дергать метод REST API чаще, чем раз в секунду, не получится  биржа не даст вам этого сделать, ясно же, что каналы связи не резиновые.

Для решения таких задач используем сокеты. Не хочу вдаваться в детали протокола WSS, наша цель в данный момент не отвлекаться на теорию, а реализовать код с использованием сокета на C#. Единственное только, не могу удержаться и не процитировать абзац из статьи на Хабре от 2009 года.

На мой взгляд, WebSocket — это самое кардинальное расширение протокола HTTP с его появления. Это не финтифлюшки, это сдвиг парадигмы HTTP.

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

				
					    function bbb(sym) {
        var s = sym.toLowerCase();
        var wsUrl = "wss://stream.binance.com:9443/ws/" + s + "@kline_1m";

        if (binaSocket != null)
            binaSocket.send(JSON.stringify({ method: "unsubscribe", topic: "kline_1m" }));

        binaSocket = new WebSocket(wsUrl);
        binaSocket.onmessage = function (event) {
            var obj = JSON.parse(event.data);
            if (obj.error) return;
            var k = obj.k;
            $("#opncls").html(k.o + " / " + k.c);
            $("#higlow").html(k.h + " / " + k.l);
            $("#volclt").html(k.v + " / " + (new Date(k.T + 1)).toLocaleTimeString().substr(0, 5));

				
			

Вот пример кода, как подключиться к сокету Binance API на C# и начать слушать события:

				
					private bool SubscribeToOrdersUpdates(int minutesToReconnect = 20, bool spotMarg = true)
{
    if (_apiKey != null && _apiKey.IsWorking)
    {
        if (CreateListenKey(spotMarg))
        {
            var lik = spotMarg ? _listenKeySpot : _listenKeyMarg;
                var res = _socketClient!.SpotStreams.SubscribeToUserDataUpdatesAsync(
                    lik,
                    onOrderUpdateMessage => OnOrderUpdate(onOrderUpdateMessage.Data, spotMarg),
                    null,
                    onAccountPositionMessage => OnAccountUpdate(onAccountPositionMessage.Data),
                    null
                ).Result;
            if (res.Success)
            {
                if (spotMarg)
                    _socketSubscrSpot = res.Data;
                else
                    _socketSubscrMarg = res.Data;

				
			

Регистрация Windows Service:

				
					sc create CaProducts binpath="D:\publish\caSvcProducts.exe" DisplayName="CryptoAlert Products" start=auto
				
			

Обязательно ставим двойные кавычки, одинарные не работают.

Свой Logger – как отдельная dll в виде синглтона, для удобства использования во всех модулях. В сервисе подключаем nLog и передаём всё, что приходит с нашего Logger’а ему.

				
					    public class Logger
    {
        static Action<Log>? _write;
        public static void Write(Log msg) => _write?.Invoke(msg);

        static object _lockFlag = new object();
        static Logger? _instance;

        public static Logger Instance
        {
            get
            {
                lock (_lockFlag)
                {
                    if (_instance == null)
                        _instance = new Logger();
                }
                return _instance;
            }
        }
        public void Init(Action<Log> write)
        {
            _write = write;
        }
    }
				
			
0

Автор публикации

не в сети 2 недели

Андрей Мизеров

0
Комментарии: 0Публикации: 76Регистрация: 15-11-2023
Рубрики
Write a comment