From 21ba316c7c5e8e8abbbc4f5728a4fbbfb24c1bf1 Mon Sep 17 00:00:00 2001 From: Victor Lee Date: Thu, 17 Feb 2022 19:37:24 -0800 Subject: [PATCH] add trade stream to Gate.IO - fixed ExchangeMarket.Active bug --- .../API/Exchanges/GateIo/ExchangeGateIoAPI.cs | 58 +++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs index eca00387..5b206bdd 100644 --- a/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs +++ b/src/ExchangeSharp/API/Exchanges/GateIo/ExchangeGateIoAPI.cs @@ -83,7 +83,8 @@ protected override async Task> OnGetMarketSymbolsAsync() { foreach (JToken token in obj) { - symbols.Add(token["id"].ToStringInvariant()); + if (token["trade_status"].ToStringLowerInvariant() == "tradable") + symbols.Add(token["id"].ToStringInvariant()); } } return symbols; @@ -117,7 +118,7 @@ protected internal override async Task> OnGetMarketS var market = new ExchangeMarket { MarketSymbol = marketSymbolToken["id"].ToStringUpperInvariant(), - IsActive = marketSymbolToken["trade_status"].ToStringUpperInvariant() == "tradable", + IsActive = marketSymbolToken["trade_status"].ToStringLowerInvariant() == "tradable", QuoteCurrency = marketSymbolToken["quote"].ToStringUpperInvariant(), BaseCurrency = marketSymbolToken["base"].ToStringUpperInvariant(), }; @@ -433,15 +434,15 @@ protected override async Task OnCancelOrderAsync(string orderId, string symbol = await MakeJsonRequestAsync($"/spot/orders/{orderId}?currency_pair={symbol}", BaseUrl, payload, "DELETE"); } + string unixTimeInSeconds => ((long)CryptoUtility.UnixTimestampFromDateTimeSeconds(DateTime.Now)).ToStringInvariant(); protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary? payload) { if (CanMakeAuthenticatedRequest(payload)) { payload.Remove("nonce"); - var timestamp = ((long)CryptoUtility.UnixTimestampFromDateTimeSeconds(DateTime.Now)).ToStringInvariant(); request.AddHeader("KEY", PublicApiKey!.ToUnsecureString()); - request.AddHeader("Timestamp", timestamp); + request.AddHeader("Timestamp", unixTimeInSeconds); var privateApiKey = PrivateApiKey!.ToUnsecureString(); @@ -453,7 +454,7 @@ protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dicti var hashBytes = sha512Hash.ComputeHash(sourceBytes); var bodyHash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant(); var queryString = string.IsNullOrEmpty(request.RequestUri.Query) ? "" : request.RequestUri.Query.Substring(1); - var signatureString = $"{request.Method}\n{request.RequestUri.AbsolutePath}\n{queryString}\n{bodyHash}\n{timestamp}"; + var signatureString = $"{request.Method}\n{request.RequestUri.AbsolutePath}\n{queryString}\n{bodyHash}\n{unixTimeInSeconds}"; using (HMACSHA512 hmac = new HMACSHA512(Encoding.UTF8.GetBytes(privateApiKey))) { @@ -469,5 +470,52 @@ protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dicti await base.ProcessRequestAsync(request, payload); } } + + protected override async Task OnGetTradesWebSocketAsync(Func, Task> callback, params string[] marketSymbols) + { + if (marketSymbols == null || marketSymbols.Length == 0) + { + marketSymbols = (await GetMarketSymbolsAsync(true)).ToArray(); + } + return await ConnectPublicWebSocketAsync(null, messageCallback: async (_socket, msg) => + { + JToken parsedMsg = JToken.Parse(msg.ToStringFromUTF8()); + + if (parsedMsg["channel"].ToStringInvariant().Equals("spot.trades")) + { + if (parsedMsg["error"] != null) + throw new APIException($"Exchange returned error: {parsedMsg["error"].ToStringInvariant()}"); + else if (parsedMsg["result"]["status"].ToStringInvariant().Equals("success")) + { + // successfully subscribed to trade stream + } + else + { + var exchangeTrade = parsedMsg["result"].ParseTrade("amount", "price", "side", "create_time_ms", TimestampType.UnixMillisecondsDouble, "id"); + + await callback(new KeyValuePair(parsedMsg["result"]["currency_pair"].ToStringInvariant(), exchangeTrade)); + } + } + }, connectCallback: async (_socket) => + {/*{ "time": int(time.time()), + "channel": "spot.trades", + "event": "subscribe", # "unsubscribe" for unsubscription + "payload": ["BTC_USDT"] + }*/ + + // this doesn't work for some reason + //await _socket.SendMessageAsync(new + //{ + // time = unixTimeInSeconds, + // channel = "spot.trades", + // @event = "subscribe", + // payload = marketSymbols, + //}); + var quotedSymbols = marketSymbols.Select(s => $"\"{s}\""); + var combinedString = string.Join(",", quotedSymbols); + await _socket.SendMessageAsync( + $"{{ \"time\": {unixTimeInSeconds},\"channel\": \"spot.trades\",\"event\": \"subscribe\",\"payload\": [{combinedString}] }}"); + }); + } } }