├── .gitignore ├── .editorconfig ├── Huobi.SDK.Core ├── Model │ ├── PingMessage.cs │ ├── PingMessageV2.cs │ ├── PingMessageV1.cs │ ├── WebSocketAuthenticationRequest.cs │ └── WebSocketAuthenticationRequestV2.cs ├── Log │ ├── EmptyLogger.cs │ ├── ILogger.cs │ └── ConsoleLogger.cs ├── Client │ ├── WebSocketClientBase │ │ ├── AbstractWebSocketClient.cs │ │ └── GZipDecompresser.cs │ ├── OrderWebSocketClient │ │ ├── RequestOrdersWebSocketV1Client.cs │ │ ├── RequestOrderWebSocketV1Client.cs │ │ ├── SubscribeOrderWebSocketV1Client.cs │ │ ├── SubscribeOrderWebSocketV2Client.cs │ │ └── SubscribeTradeClearWebSocketV2Client.cs │ ├── AccountWebSocketClient │ │ ├── RequestAccountWebSocketV1Client.cs │ │ ├── SubscribeAccountWebSocketV2Client.cs │ │ └── SubscribeAccountWebSocketV1Client.cs │ ├── MarketWebSocketClient │ │ ├── BestBidOfferWebSocketClient.cs │ │ ├── MarketTickerWebSocketClient.cs │ │ ├── TradeWebSocketClient.cs │ │ ├── Last24hCandlestickWebSocketClient.cs │ │ ├── DepthWebSocketClient.cs │ │ └── CandlestickWebSocketClient.cs │ └── StableCoinClient.cs ├── RequestBuilder │ ├── PublicUrlBuilder.cs │ ├── WebSocketV1RequestBuilder.cs │ └── WebSocketV2RequestBuilder.cs ├── Huobi.SDK.Core.csproj ├── GetRequest.cs └── HttpRequest.cs ├── Huobi.SDK.Model ├── Response │ ├── ResponseCode.cs │ ├── Auth │ │ ├── WebSocketV1AuthResponse.cs │ │ └── WebSocketV2AuthResponse.cs │ ├── Account │ │ ├── AccountTransferResponse.cs │ │ ├── AccountFeeSwitchResponse.cs │ │ ├── TransferAccountResponse.cs │ │ ├── GetAccountOverviewInfoResponse.cs │ │ ├── TransferPointResponse.cs │ │ ├── GetAccountAssetValuationResponse.cs │ │ ├── GetAccountSwitchUserInfoResponse.cs │ │ ├── GetAccountInfoResponse.cs │ │ ├── RequestAccountResponse.cs │ │ ├── GetPointBalanceResponse.cs │ │ ├── SubscribeAccountV2Response.cs │ │ ├── SubscribeAccountV1Response.cs │ │ ├── GetAccountValuationResponse.cs │ │ ├── GetAccountLedgerResponse.cs │ │ └── GetAccountBalanceResponse.cs │ ├── Common │ │ ├── GetTimestampResponse.cs │ │ ├── GetCurrencysResponse.cs │ │ └── GetMarketStatusResponse.cs │ ├── SubUser │ │ ├── SubUserApiKeyDeletionResponse.cs │ │ ├── SubUserTrustCreditResponse.cs │ │ ├── GetUIDResponse.cs │ │ ├── LockUnLockSubUserResponse.cs │ │ ├── GetSubUserUserStateResponse.cs │ │ ├── CreateSubUserResponse.cs │ │ ├── SubUserApiKeyModificationResponse.cs │ │ ├── DeductModeSubUserResponse.cs │ │ ├── GetSubUserAccountBalancesResponse.cs │ │ ├── GetSubUserUserListResponse.cs │ │ ├── SubUserTradableMarketResponse.cs │ │ ├── SubUserApiKeyGenerationResponse.cs │ │ ├── SubUserTransferabilityResponse.cs │ │ ├── GetSubUserApiKeyResponse.cs │ │ ├── GetSubUserAccountListResponse.cs │ │ ├── GetSubUserAccountBalanceResponse.cs │ │ └── GetSubUserDepositHistoryResponse.cs │ ├── AlgoOrder │ │ ├── PlaceOrderResponse.cs │ │ ├── CancelOrdersResponse.cs │ │ ├── GetOpenOrdersResponse.cs │ │ ├── GetSpecificOrderResponse.cs │ │ └── GetHistoryOrdersResponse.cs │ ├── WebSocketBase │ │ ├── WebSocketResponseBase.cs │ │ ├── WebSocketV2ResponseBase.cs │ │ └── WebSocketV1ResponseBase.cs │ ├── Margin │ │ ├── GeneralRepayResponse.cs │ │ ├── GetSubMarginLimitResponse.cs │ │ ├── GetRepaymentResponse.cs │ │ ├── GetCrossLoanInfoResponse.cs │ │ ├── GetIsolatedLoanInfoResponse.cs │ │ └── GetIsolatedMarginAccountResponse.cs │ ├── Order │ │ ├── AutoPlaceResponse.cs │ │ ├── CancelAllAfterResponse.cs │ │ ├── PlaceOrderResponse.cs │ │ ├── CancelOrderByIdResponse.cs │ │ ├── CancelOrderByClientResponse.cs │ │ ├── GetTransactFeeRate.cs │ │ ├── GetFeeResponse.cs │ │ ├── CancelOrdersByCriteriaResponse.cs │ │ ├── PlaceOrdersResponse.cs │ │ ├── GetLastTradeResponse.cs │ │ ├── GetLastTradesResponse.cs │ │ └── CancelOrdersByIdsResponse.cs │ ├── ETF │ │ └── SwapETFResponse.cs │ ├── Transfer │ │ └── TransferResponse.cs │ ├── Wallet │ │ ├── CancelWithdrawCurrencyResponse.cs │ │ ├── WithdrawCurrencyResponse.cs │ │ ├── GetDepositAddressResponse.cs │ │ ├── GetWithdrawAddressResponse.cs │ │ └── GetWithdrawQuotaResponse.cs │ ├── Market │ │ ├── SubscribeTickerResponse.cs │ │ ├── SubscribeDepthResponse.cs │ │ ├── SubscribeMarketByPriceResponse.cs │ │ ├── SubscribeBestBidOfferResponse.cs │ │ ├── GetDepthResponse.cs │ │ ├── SubscribeTradeResponse.cs │ │ ├── SubscribeCandlestickResponse.cs │ │ ├── GetCandlestickResponse.cs │ │ ├── SubscribeLast24hCandlestickResponse.cs │ │ ├── GetLast24hCandlestickResponse.cs │ │ ├── GetLast24hCandlesticksResponse.cs │ │ └── GetLast24hCandlestickAskBidResponse.cs │ └── StableCoin │ │ ├── ExchangeStableCoinResponse.cs │ │ └── GetStableCoinResponse.cs ├── Request │ ├── AlgoOrder │ │ ├── CancelOrdersRequest.cs │ │ └── PlaceOrderRequest.cs │ ├── PostRequestBase.cs │ ├── Margin │ │ ├── GeneralRepayRequest.cs │ │ └── GetRepaymentRequest.cs │ ├── Account │ │ ├── TransferPointRequest.cs │ │ ├── AccountTransferRequest.cs │ │ └── TransferAccountRequest.cs │ ├── Order │ │ ├── CancelOrdersByIdsRequest.cs │ │ ├── CancelOrdersByCriteriaRequest.cs │ │ ├── RequestOrdersRequest.cs │ │ ├── PlaceOrderRequest.cs │ │ └── AutoPlaceRequest.cs │ ├── SubUser │ │ └── CreateSubUserRequest.cs │ └── Wallet │ │ └── WithdrawRequest.cs └── Huobi.SDK.Model.csproj ├── Huobi.SDK.Example ├── appsettings.json ├── Timestamp.cs ├── Huobi.SDK.Example.csproj ├── Huobi.SDK.Example.csproj1 ├── AppLogger.cs ├── Program.cs ├── Config.cs └── StableCoinClientExample.cs ├── .vscode ├── tasks.json └── launch.json ├── Huobi.SDK.Core.Test ├── GZipDecompresserTest.cs ├── Huobi.SDK.Core.Test.csproj └── RequestBuilder │ ├── PublicUrlBuilderTest.cs │ ├── SignerTest.cs │ ├── SignerED25519Test.cs │ ├── WebSocketRequestBuilderTest.cs │ ├── PrivateUrlBuilderTest.cs │ └── WebSocketRequestBuilderV2Test.cs └── Huobi.SDK.sln /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | bin/ 3 | obj/ 4 | .vs/ 5 | packages/ 6 | Huobi.SDK.Example/key.json 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # IDE0005: Using 指令是不需要的。 4 | dotnet_diagnostic.IDE0005.severity = none 5 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Model/PingMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Core.Model 2 | { 3 | public class PingMessage 4 | { 5 | public long ping; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/ResponseCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Huobi.SDK.Model.Response 3 | { 4 | public enum ResponseCode 5 | { 6 | Success = 200 7 | } 8 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/AlgoOrder/CancelOrdersRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Request.AlgoOrder 2 | { 3 | public class CancelOrdersRequest : PostRequestBase 4 | { 5 | public string[] clientOrderIds; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Auth/WebSocketV1AuthResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Auth 4 | { 5 | public class WebSocketV1AuthResponse : WebSocketV1ResponseBase 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Auth/WebSocketV2AuthResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Auth 4 | { 5 | public class WebSocketV2AuthResponse : WebSocketV2ResponseBase 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Host": "api.huobi.pro", 3 | "AccountId": "31252055", 4 | "SubUserId": "5678", 5 | "PublicKey": "", 6 | "PrivateKey": "", 7 | "Sign": "25519", 8 | "AccessKey": "", 9 | "SecretKey": "" 10 | } 11 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Log/EmptyLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Huobi.SDK.Core.Log 3 | { 4 | public class EmptyLogger : ILogger 5 | { 6 | public void Log(LogLevel level, string message) 7 | { 8 | return; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Model/PingMessageV2.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Core.Model 2 | { 3 | public class PingMessageV2 4 | { 5 | public class Data 6 | { 7 | public long ts; 8 | } 9 | 10 | public string action; 11 | public Data data; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/PostRequestBase.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request 4 | { 5 | public class PostRequestBase 6 | { 7 | public string ToJson() 8 | { 9 | return JsonConvert.SerializeObject(this); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/AccountTransferResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Account 2 | { 3 | public class AccountTransferResponse 4 | { 5 | public string success; 6 | 7 | public long data; 8 | 9 | public long code; 10 | 11 | public string message; 12 | } 13 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core/Model/PingMessageV1.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Core.Model 2 | { 3 | public class PingMessageV1 4 | { 5 | public string op; 6 | 7 | public long ts; 8 | 9 | public bool IsPing() 10 | { 11 | return this != null && ts != 0 && op.Equals("ping"); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Margin/GeneralRepayRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Request.Margin 2 | { 3 | public class GeneralRepayRequest : PostRequestBase 4 | { 5 | public string accountId; 6 | 7 | public string currency; 8 | 9 | public string amount; 10 | 11 | public string transactId; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Log/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Core.Log 2 | { 3 | public interface ILogger 4 | { 5 | void Log(LogLevel level, string message); 6 | } 7 | 8 | public enum LogLevel 9 | { 10 | Fatal, 11 | Error, 12 | Warn, 13 | Info, 14 | Debug, 15 | Trace 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/Huobi.SDK.Example/Huobi.SDK.Example.csproj" 11 | // 替换为你的项目文件 12 | ], 13 | "problemMatcher": "$msCompile" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core/Log/ConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Huobi.SDK.Core.Log 3 | { 4 | public class ConsoleLogger : ILogger 5 | { 6 | public void Log(LogLevel level, string message) 7 | { 8 | string dateTime = DateTime.UtcNow.ToString("s"); 9 | Console.WriteLine($"{dateTime} | {level} | {message}"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Common/GetTimestampResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Huobi.SDK.Model.Response.Common 3 | { 4 | public class GetTimestampResponse 5 | { 6 | /// 7 | /// Response status 8 | /// 9 | public string status; 10 | 11 | /// 12 | /// Response body 13 | /// 14 | public string data; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Margin/GetRepaymentRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Request.Margin 2 | { 3 | public class GetRepaymentRequest 4 | { 5 | public string repayId; 6 | 7 | public string accountId; 8 | 9 | public string currency; 10 | 11 | public long startTime; 12 | 13 | public long endTime; 14 | 15 | public string sort; 16 | 17 | public int limit; 18 | 19 | public long fromId; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Account/TransferPointRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Account 4 | { 5 | public class TransferPointRequest 6 | { 7 | public string fromUid; 8 | 9 | public string toUid; 10 | 11 | public long groupId; 12 | 13 | public string amount; 14 | 15 | public string ToJson() 16 | { 17 | return JsonConvert.SerializeObject(this); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Common/GetCurrencysResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Common 2 | { 3 | /// 4 | /// GetCurrencys response 5 | /// 6 | public class GetCurrencysResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// Response body 15 | /// 16 | public string[] data; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/SubUserApiKeyDeletionResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class SubUserApiKeyDeletionResponse 6 | { 7 | public int code; 8 | 9 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 10 | public string message; 11 | 12 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 13 | public string data; 14 | } 15 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/GZipDecompresserTest.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Xunit; 3 | 4 | namespace Huobi.SDK.Core.Test 5 | { 6 | public class GZipDecompresserTest 7 | { 8 | [Fact] 9 | public void Decompress_Success() 10 | { 11 | byte[] compressed = GZipDecompresser.Compress("Huobi"); 12 | 13 | string origin = GZipDecompresser.Decompress(compressed); 14 | 15 | Assert.Equal("Huobi", origin); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Order/CancelOrdersByIdsRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Order 4 | { 5 | public class CancelOrdersByIdsRequest 6 | { 7 | [JsonProperty(PropertyName = "order-ids")] 8 | public string[] OrderIds; 9 | 10 | [JsonProperty(PropertyName = "client-order-ids")] 11 | public string[] ClientOrderIds; 12 | 13 | public string ToJson() 14 | { 15 | return JsonConvert.SerializeObject(this); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Account/AccountTransferRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Account 4 | { 5 | public class AccountTransferRequest 6 | { 7 | public string from; 8 | 9 | public string to; 10 | 11 | public string currency; 12 | 13 | public float amount; 14 | 15 | [JsonProperty("margin-account")] 16 | public string marginAccount; 17 | public string ToJson() 18 | { 19 | return JsonConvert.SerializeObject(this); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/WebSocketClientBase/AbstractWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.Log; 3 | 4 | namespace Huobi.SDK.Core.Client.WebSocketClientBase 5 | { 6 | public abstract class AbstractWebSocketClient 7 | { 8 | protected ILogger _logger = new ConsoleLogger(); 9 | 10 | public void SetLogger(ILogger logger) 11 | { 12 | _logger = logger ?? new EmptyLogger(); 13 | } 14 | 15 | public abstract void Connect(bool autoConnect = true); 16 | 17 | public abstract void Disconnect(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Order/CancelOrdersByCriteriaRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Order 4 | { 5 | public class CancelOrdersByCriteriaRequest 6 | { 7 | [JsonProperty(PropertyName = "account-id")] 8 | public string AccountId; 9 | 10 | public string symbol; 11 | 12 | public string side; 13 | 14 | public int size; 15 | 16 | public string types; 17 | 18 | public string ToJson() 19 | { 20 | return JsonConvert.SerializeObject(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/SubUserTrustCreditResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class SubUserTrustCreditResponse 6 | { 7 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 8 | public string Status { get; set; } 9 | 10 | [JsonProperty("ts", NullValueHandling = NullValueHandling.Ignore)] 11 | public long Ts { get; set; } 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public bool Data { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/SubUser/CreateSubUserRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.SubUser 4 | { 5 | /// 6 | /// Create SubUser request 7 | /// 8 | public class CreateSubUserRequest 9 | { 10 | public UserList[] userList; 11 | 12 | public class UserList 13 | { 14 | public string userName; 15 | 16 | public string note; 17 | } 18 | 19 | public string ToJson() 20 | { 21 | return JsonConvert.SerializeObject(this); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Wallet/WithdrawRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Wallet 4 | { 5 | public class WithdrawRequest 6 | { 7 | public string address; 8 | 9 | public string amount; 10 | 11 | public string currency; 12 | 13 | public string fee; 14 | 15 | public string chain; 16 | 17 | public string addrTag; 18 | 19 | public string clientOrderId; 20 | 21 | public string ToJson() 22 | { 23 | return JsonConvert.SerializeObject(this); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetUIDResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.SubUser 2 | { 3 | /// 4 | /// Create SubUser Response 5 | /// 6 | public class GetUIDResponse 7 | { 8 | /// 9 | /// Status code 10 | /// 11 | public int code; 12 | 13 | /// 14 | /// Error message (if any) 15 | /// 16 | public string message; 17 | 18 | /// 19 | /// Response body 20 | /// 21 | public long? data; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Model/WebSocketAuthenticationRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Core.Model 4 | { 5 | public class WebSocketAuthenticationRequest 6 | { 7 | public string op { get { return "auth"; } } 8 | public string AccessKeyId; 9 | public string SignatureMethod { get { return "HmacSHA256"; } } 10 | public string SignatureVersion { get { return "2"; } } 11 | public string Timestamp; 12 | public string Signature; 13 | 14 | public string ToJson() 15 | { 16 | return JsonConvert.SerializeObject(this); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/AlgoOrder/PlaceOrderResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.AlgoOrder 2 | { 3 | public class PlaceOrderResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data data; 19 | 20 | public class Data 21 | { 22 | public string clientOrderId; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/WebSocketBase/WebSocketResponseBase.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.WebSocket 2 | { 3 | /// 4 | /// WebSocket response base 5 | /// 6 | public abstract class WebSocketResponseBase 7 | { 8 | /// 9 | /// Subscribe status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// Data stream 15 | /// 16 | public string ch; 17 | 18 | /// 19 | /// Respond timestamp in millisecond 20 | /// 21 | public long ts; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/AlgoOrder/PlaceOrderRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Request.AlgoOrder 2 | { 3 | public class PlaceOrderRequest : PostRequestBase 4 | { 5 | public int accountId; 6 | 7 | public string symbol; 8 | 9 | public string orderPrice; 10 | 11 | public string orderSide; 12 | 13 | public string orderSize; 14 | 15 | public string orderValue; 16 | 17 | public string timeInForce; 18 | 19 | public string orderType; 20 | 21 | public string clientOrderId; 22 | 23 | public string stopPrice; 24 | 25 | public string trailingRate; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/RequestBuilder/PublicUrlBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Core.RequestBuilder 2 | { 3 | public class PublicUrlBuilder 4 | { 5 | private readonly string _host; 6 | 7 | public PublicUrlBuilder(string host) 8 | { 9 | _host = host; 10 | } 11 | 12 | public string Build(string path, GetRequest request = null) 13 | { 14 | if (request != null) 15 | { 16 | return $"https://{_host}{path}?{request.BuildParams()}"; 17 | } 18 | else 19 | { 20 | return $"https://{_host}{path}"; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Margin/GeneralRepayResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Margin 2 | { 3 | public class GeneralRepayResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data[] data; 19 | 20 | public class Data 21 | { 22 | public string repayId; 23 | 24 | public long repayTime; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/AlgoOrder/CancelOrdersResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.AlgoOrder 2 | { 3 | public class CancelOrdersResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data data; 19 | 20 | public class Data 21 | { 22 | public string[] accepted; 23 | 24 | public string[] rejected; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/AccountFeeSwitchResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class AccountFeeSwitchResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code { get; set; } 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message { get; set; } 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public object Data { get; set; } 15 | 16 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 17 | public bool Success { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/LockUnLockSubUserResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.SubUser 2 | { 3 | /// 4 | /// LockSubUser and UnLockSubUser Response 5 | /// 6 | public class LockUnLockSubUserResponse 7 | { 8 | /// 9 | /// Status code 10 | /// 11 | public int code; 12 | 13 | public State data; 14 | 15 | public class State 16 | { 17 | /// 18 | /// sub user id 19 | /// 20 | public int subUid; 21 | 22 | /// 23 | /// sub user state 24 | /// 25 | public string userState; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/WebSocketBase/WebSocketV2ResponseBase.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.WebSocket 2 | { 3 | /// 4 | /// WebSocket v2 response base 5 | /// 6 | public abstract class WebSocketV2ResponseBase 7 | { 8 | /// 9 | /// Action 10 | /// 11 | public string action; 12 | 13 | /// 14 | /// Response code 15 | /// 16 | public int code; 17 | 18 | /// 19 | /// Channel 20 | /// 21 | public string ch; 22 | 23 | /// 24 | /// Error message (if any) 25 | /// 26 | public string message; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/TransferAccountResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class TransferAccountResponse 6 | { 7 | public string status; 8 | 9 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 10 | public string errCode; 11 | 12 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 13 | public string errMessage; 14 | 15 | public TransferResponse data; 16 | 17 | public class TransferResponse 18 | { 19 | [JsonProperty("transact-id")] 20 | public int transactId; 21 | 22 | [JsonProperty("transact-time")] 23 | public long transactTime; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/AutoPlaceResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | public class AutoPlaceResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 11 | public bool Success; 12 | 13 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 14 | public string Message; 15 | 16 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 17 | public AutoPlace Data; 18 | 19 | public class AutoPlace 20 | { 21 | [JsonProperty("order-id", NullValueHandling = NullValueHandling.Ignore)] 22 | public long OrderId; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserUserStateResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class GetSubUserUserStateResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public UserStateData Data; 15 | 16 | public class UserStateData 17 | { 18 | [JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)] 19 | public long Uid; 20 | 21 | [JsonProperty("userState", NullValueHandling = NullValueHandling.Ignore)] 22 | public string UserState; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/Huobi.SDK.Core.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 6 | false 7 | 2.2.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Model/WebSocketAuthenticationRequestV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Huobi.SDK.Core.Model 5 | { 6 | public class WebSocketAuthenticationRequestV2 7 | { 8 | public class Params 9 | { 10 | public string authType { get { return "api"; } } 11 | public string accessKey; 12 | public string signatureMethod { get { return "HmacSHA256"; } } 13 | public string signatureVersion { get { return "2.1"; } } 14 | public string timestamp; 15 | public string signature; 16 | } 17 | 18 | public string action { get { return "req"; } } 19 | public string ch { get { return "auth"; } } 20 | public Params @params; 21 | 22 | public string ToJson() 23 | { 24 | return JsonConvert.SerializeObject(this); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/CancelAllAfterResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | public class CancelAllAfterResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("", NullValueHandling = NullValueHandling.Ignore)] 14 | public CancelAllAfter Data; 15 | 16 | public class CancelAllAfter 17 | { 18 | [JsonProperty("currentTime", NullValueHandling = NullValueHandling.Ignore)] 19 | public long CurrentTime; 20 | 21 | [JsonProperty("triggerTime", NullValueHandling = NullValueHandling.Ignore)] 22 | public long TriggerTime; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/CreateSubUserResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.SubUser 2 | { 3 | /// 4 | /// Create SubUser Response 5 | /// 6 | public class CreateSubUserResponse 7 | { 8 | /// 9 | /// Status code 10 | /// 11 | public int code; 12 | 13 | /// 14 | /// Error message (if any) 15 | /// 16 | public string message; 17 | 18 | /// 19 | /// Response body 20 | /// 21 | public Creation[] data; 22 | 23 | public class Creation 24 | { 25 | public string userName; 26 | 27 | public string note; 28 | 29 | public long uid; 30 | 31 | public string errCode; 32 | 33 | public string errMessage; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Account/TransferAccountRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Account 4 | { 5 | public class TransferAccountRequest 6 | { 7 | [JsonProperty("from-user")] 8 | public long fromUser; 9 | 10 | [JsonProperty("from-account-type")] 11 | public string fromAccountType; 12 | 13 | [JsonProperty("from-account")] 14 | public long fromAccount; 15 | 16 | [JsonProperty("to-user")] 17 | public long toUser; 18 | 19 | [JsonProperty("to-account-type")] 20 | public string toAccountType; 21 | 22 | [JsonProperty("to-account")] 23 | public long toAccount; 24 | 25 | public string currency; 26 | 27 | public string amount; 28 | 29 | public string ToJson() 30 | { 31 | return JsonConvert.SerializeObject(this); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/ETF/SwapETFResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.ETF 4 | { 5 | /// 6 | /// SwapIn and SwapOut response 7 | /// 8 | public class SwapETFResponse 9 | { 10 | /// 11 | /// Status code 12 | /// 13 | public int code; 14 | 15 | /// 16 | /// Whether the response success or not 17 | /// 18 | public bool success; 19 | 20 | /// 21 | /// Error message (if any) 22 | /// 23 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 24 | public string message; 25 | 26 | /// 27 | /// Response body 28 | /// 29 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 30 | public object data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/WebSocketBase/WebSocketV1ResponseBase.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.WebSocket 4 | { 5 | /// 6 | /// WebSocket v1 response base 7 | /// 8 | public abstract class WebSocketV1ResponseBase 9 | { 10 | /// 11 | /// Timestamp 12 | /// 13 | public long ts; 14 | 15 | /// 16 | /// Operation 17 | /// 18 | public string op; 19 | 20 | /// 21 | /// Error code 22 | /// 23 | [JsonProperty("err-code")] 24 | public int errCode; 25 | 26 | /// 27 | /// Topic 28 | /// 29 | public string topic; 30 | 31 | /// 32 | /// Client id 33 | /// 34 | public string cid; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/Timestamp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Huobi.SDK.Example 3 | { 4 | public class Timestamp 5 | { 6 | public static string SToLocal(long ts) 7 | { 8 | return SToDateTime(ts).ToLocalTime().ToString("s"); 9 | } 10 | 11 | public static string MSToLocal(string ts) 12 | { 13 | return MSToLocal(long.Parse(ts)); 14 | } 15 | 16 | public static string MSToLocal(long ts) 17 | { 18 | return MSToDateTime(ts).ToLocalTime().ToString("s"); 19 | } 20 | 21 | private static DateTime MSToDateTime(long ts) 22 | { 23 | return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ts); 24 | } 25 | 26 | private static DateTime SToDateTime(long ts) 27 | { 28 | return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(ts); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Huobi.SDK.Model.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 3.1.426 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | // { 8 | // "name": ".NET Core Launch (console)", 9 | // "type": "coreclr", 10 | // "request": "launch", 11 | // "preLaunchTask": "build", 12 | // "program": "${workspaceFolder}/bin/Debug/net6.0/MyCSharpApp.dll", // 修改为你的项目输出路径 13 | // "args": [], 14 | // "cwd": "${workspaceFolder}", 15 | // "stopAtEntry": false, 16 | // "serverReadyAction": { 17 | // "action": "openExternally", 18 | // "pattern": "\\bNow listening on:\\s+(https?://\\S+)" 19 | // }, 20 | // "env": { 21 | // "ASPNETCORE_ENVIRONMENT": "Development" 22 | // }, 23 | // "sourceFileMap": { 24 | // "/Views": "${workspaceFolder}/Views" 25 | // } 26 | // } 27 | ] 28 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountOverviewInfoResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class GetAccountOverviewInfoResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code { get; set; } 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message { get; set; } 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public GetAccountOverviewInfo Data { get; set; } 15 | 16 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 17 | public bool Success { get; set; } 18 | 19 | public class GetAccountOverviewInfo 20 | { 21 | [JsonProperty("currency", NullValueHandling = NullValueHandling.Ignore)] 22 | public string Currency { get; set; } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/TransferPointResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class TransferPointResponse 6 | { 7 | /// 8 | /// Status code 9 | /// 10 | public int code; 11 | 12 | /// 13 | /// Error message (if any) 14 | /// 15 | public string message; 16 | 17 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 18 | public string success; 19 | 20 | public Data data; 21 | 22 | public class Data 23 | { 24 | /// 25 | /// Transaction ID 26 | /// 27 | public string transactId; 28 | 29 | /// 30 | /// Transaction time (unix time in millisecond) 31 | /// 32 | public long transactTime; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/PlaceOrderResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// PlaceOrder response 7 | /// 8 | public class PlaceOrderResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Order id 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public string data; 20 | 21 | /// 22 | /// Error code 23 | /// 24 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorCode; 26 | 27 | /// 28 | /// Error message 29 | /// 30 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 31 | public string errorMessage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Transfer/TransferResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Transfer 4 | { 5 | /// 6 | /// Transfer response 7 | /// 8 | public class TransferResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Transfer id 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public long data; 20 | 21 | /// 22 | /// Error code 23 | /// 24 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorCode; 26 | 27 | /// 28 | /// Error message 29 | /// 30 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 31 | public string errorMessage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Order/RequestOrdersRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Order 4 | { 5 | public class RequestOrdersRequest 6 | { 7 | public string op { get { return "req"; } } 8 | 9 | public string topic { get { return "orders.list"; } } 10 | 11 | public string cid; 12 | 13 | [JsonProperty(PropertyName = "account-id")] 14 | public int AccountId; 15 | 16 | public string symbol; 17 | 18 | public string types; 19 | 20 | public string states; 21 | 22 | [JsonProperty(PropertyName = "start-date")] 23 | public string StartDate; 24 | 25 | [JsonProperty(PropertyName = "end-date")] 26 | public string EndDate; 27 | 28 | public string from; 29 | 30 | public string direct; 31 | 32 | public string size; 33 | 34 | public string ToJson() 35 | { 36 | return JsonConvert.SerializeObject(this); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/CancelOrderByIdResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// CancelOrderById response 7 | /// 8 | public class CancelOrderByIdResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Order id 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public string data; 20 | 21 | /// 22 | /// Error code 23 | /// 24 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorCode; 26 | 27 | /// 28 | /// Error message 29 | /// 30 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 31 | public string errorMessage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Order/PlaceOrderRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Order 4 | { 5 | public class PlaceOrderRequest 6 | { 7 | [JsonProperty(PropertyName="account-id")] 8 | public string AccountId; 9 | 10 | public string symbol; 11 | 12 | public string type; 13 | 14 | public string amount; 15 | 16 | public string price; 17 | 18 | public string source; 19 | 20 | [JsonProperty(PropertyName="client-order-id")] 21 | public string ClientOrderId; 22 | 23 | [JsonProperty(PropertyName="self-match-prevent")] 24 | public int SelfMatchPrevent; 25 | 26 | [JsonProperty(PropertyName = "stop-price")] 27 | public string StopPrice; 28 | 29 | [JsonProperty(PropertyName = "operator")] 30 | public string Operator; 31 | 32 | public string ToJson() 33 | { 34 | return JsonConvert.SerializeObject(this); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Margin/GetSubMarginLimitResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Margin 4 | { 5 | public class GetSubMarginLimitResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 14 | public string Status; 15 | 16 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 17 | public MarginLimit[] Data; 18 | 19 | public class MarginLimit 20 | { 21 | [JsonProperty("currency", NullValueHandling = NullValueHandling.Ignore)] 22 | public string Currency; 23 | 24 | [JsonProperty("maxHoldings", NullValueHandling = NullValueHandling.Ignore)] 25 | public string MaxHoldings; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Wallet/CancelWithdrawCurrencyResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Wallet 4 | { 5 | /// 6 | /// WithdrawCurrency response 7 | /// 8 | public class WithdrawCurrencyResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Transfer id 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public long data; 20 | 21 | /// 22 | /// Error code 23 | /// 24 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorCode; 26 | 27 | /// 28 | /// Error message 29 | /// 30 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 31 | public string errorMessage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Wallet/WithdrawCurrencyResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Wallet 4 | { 5 | /// 6 | /// CancelWithdrawCurrency response 7 | /// 8 | public class CancelWithdrawCurrencyResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Transfer id 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public int data; 20 | 21 | /// 22 | /// Error code 23 | /// 24 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorCode; 26 | 27 | /// 28 | /// Error message 29 | /// 30 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 31 | public string errorMessage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/CancelOrderByClientResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// CancelOrderByClientResponse response 7 | /// 8 | public class CancelOrderByClientResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Cancellation status code 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public int data; 20 | 21 | /// 22 | /// Error code 23 | /// 24 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorCode; 26 | 27 | /// 28 | /// Error message 29 | /// 30 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 31 | public string errorMessage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/SubUserApiKeyModificationResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class SubUserApiKeyModificationResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public ApiKeyModification Data; 15 | 16 | public class ApiKeyModification 17 | { 18 | [JsonProperty("note", NullValueHandling = NullValueHandling.Ignore)] 19 | public string Note; 20 | 21 | [JsonProperty("permission", NullValueHandling = NullValueHandling.Ignore)] 22 | public string Permission; 23 | 24 | [JsonProperty("ipAddresses", NullValueHandling = NullValueHandling.Ignore)] 25 | public string IpAddresses; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountAssetValuationResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class GetAccountAssetValuationResponse 6 | { 7 | /// 8 | /// Status code 9 | /// 10 | public int code; 11 | 12 | /// 13 | /// Error message (if any) 14 | /// 15 | public string message; 16 | 17 | [JsonProperty("ok", NullValueHandling = NullValueHandling.Ignore)] 18 | public string ok; 19 | 20 | /// 21 | /// Response body 22 | /// 23 | public Data data; 24 | 25 | public class Data 26 | { 27 | /// 28 | /// The valuation according to the certain fiat currency 29 | /// 30 | public string balance; 31 | 32 | /// 33 | /// Return time; 34 | /// 35 | public long timestamp; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Huobi.SDK.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 3.1.426 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/RequestBuilder/PublicUrlBuilderTest.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core; 2 | using Huobi.SDK.Core.RequestBuilder; 3 | using Xunit; 4 | 5 | namespace Huobi.SDK.Core.Test.RequestBuilder 6 | { 7 | public class PublicUrlBuilderTest 8 | { 9 | [Fact] 10 | public void Build_NoRequestParameter_Success() 11 | { 12 | var builder = new PublicUrlBuilder("api.huobi.pro"); 13 | 14 | string result = builder.Build("/common/symbols"); 15 | 16 | Assert.Equal("https://api.huobi.pro/common/symbols", result); 17 | } 18 | 19 | [Fact] 20 | public void Build_RequestParameter_Success() 21 | { 22 | var builder = new PublicUrlBuilder("api.huobi.pro"); 23 | var request = new GetRequest() 24 | .AddParam("symbol", "btcusdt") 25 | .AddParam("period", "1min") 26 | .AddParam("size", "1"); 27 | 28 | string result = builder.Build("/market/history/kline", request); 29 | 30 | Assert.Equal("https://api.huobi.pro/market/history/kline?period=1min&size=1&symbol=btcusdt", result); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeTickerResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | public class SubscribeTickerResponse : WebSocketResponseBase 6 | { 7 | /// 8 | /// Response body from req 9 | /// 10 | public Tick data; 11 | 12 | /// 13 | /// Response body from sub 14 | /// 15 | public Tick tick; 16 | 17 | /// 18 | /// Ticker 19 | /// 20 | public class Tick 21 | { 22 | public float amount; 23 | 24 | public int count; 25 | 26 | public float open; 27 | 28 | public float close; 29 | 30 | public float low; 31 | 32 | public float high; 33 | 34 | public float vol; 35 | 36 | public float bid; 37 | 38 | public float bidSize; 39 | 40 | public float ask; 41 | 42 | public float askSize; 43 | 44 | public float lastPrice; 45 | 46 | public float lastSize; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/DeductModeSubUserResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class DeductModeSubUserResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public DeductModeSubUser[] Data; 15 | 16 | public class DeductModeSubUser 17 | { 18 | [JsonProperty("subUid", NullValueHandling = NullValueHandling.Ignore)] 19 | public string SubUid; 20 | 21 | [JsonProperty("deductMode", NullValueHandling = NullValueHandling.Ignore)] 22 | public string DeductMode; 23 | 24 | [JsonProperty("errCode", NullValueHandling = NullValueHandling.Ignore)] 25 | public string ErrCode; 26 | 27 | [JsonProperty("errMessage", NullValueHandling = NullValueHandling.Ignore)] 28 | public string errMessage; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Margin/GetRepaymentResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Margin 2 | { 3 | public class GetRepaymentResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data[] data; 19 | 20 | public class Data 21 | { 22 | public string repayId; 23 | 24 | public long repayTime; 25 | 26 | public string accountId; 27 | 28 | public string currency; 29 | 30 | public string repaidAmount; 31 | 32 | public TransactId transactIds; 33 | 34 | public class TransactId 35 | { 36 | public long transactId; 37 | 38 | public string repaidPrincipal; 39 | 40 | public string repaidInterest; 41 | 42 | public string paidHT; 43 | 44 | public string paidPoint; 45 | } 46 | } 47 | 48 | public long nextId; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserAccountBalancesResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.SubUser 2 | { 3 | /// 4 | /// GetSubUserAccountBalance response 5 | /// 6 | public class GetSubUserAccountBalancesResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// Response body 15 | /// 16 | public Balance[] data; 17 | 18 | /// 19 | /// Account balance 20 | /// 21 | public class Balance 22 | { 23 | /// 24 | /// The currency of this balance 25 | /// 26 | public string currency; 27 | 28 | /// 29 | /// The account type 30 | /// Possible values: [spot, margin, point, super-margin] 31 | /// 32 | public string type; 33 | 34 | /// 35 | /// The total balance in the main currency unit including all balance and frozen banlance 36 | /// 37 | public string balance; 38 | 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeDepthResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | /// 6 | /// SubscribeDepth response 7 | /// 8 | public class SubscribeDepthResponse : WebSocketResponseBase 9 | { 10 | /// 11 | /// Response body from req 12 | /// 13 | public Tick data; 14 | 15 | /// 16 | /// Response body from sub 17 | /// 18 | public Tick tick; 19 | 20 | public class Tick 21 | { 22 | /// 23 | /// Timestamp in millionsecond 24 | /// 25 | public long ts; 26 | 27 | /// 28 | /// Internal data 29 | /// 30 | public long version; 31 | 32 | /// 33 | /// The current all bids in format [price, quote volume] 34 | /// 35 | public float[][] bids; 36 | 37 | /// 38 | /// The current all asks in format [price, quote volume] 39 | /// 40 | public float[][] asks; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserUserListResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class GetSubUserUserListResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public SubUserUserList Data; 15 | 16 | [JsonProperty("nextId", NullValueHandling = NullValueHandling.Ignore)] 17 | public long NextId; 18 | 19 | public class SubUserUserList 20 | { 21 | [JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)] 22 | public long Uid; 23 | 24 | [JsonProperty("userState", NullValueHandling = NullValueHandling.Ignore)] 25 | public string UserState; 26 | 27 | [JsonProperty("subUserName", NullValueHandling = NullValueHandling.Ignore)] 28 | public string SubUserName; 29 | 30 | [JsonProperty("note", NullValueHandling = NullValueHandling.Ignore)] 31 | public string Note; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Huobi.SDK.Example/Huobi.SDK.Example.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 2.2.0 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/Huobi.SDK.Example.csproj1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 3.1.426 6 | Exe 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountSwitchUserInfoResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class GetAccountSwitchUserInfoResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code { get; set; } 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message { get; set; } 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public GetAccountSwitchUserInfo Data { get; set; } 15 | 16 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 17 | public bool Success { get; set; } 18 | 19 | public class GetAccountSwitchUserInfo 20 | { 21 | [JsonProperty("pointSwitch", NullValueHandling = NullValueHandling.Ignore)] 22 | public int PointSwitch { get; set; } 23 | 24 | [JsonProperty("currencySwitch", NullValueHandling = NullValueHandling.Ignore)] 25 | public int CurrencySwitch { get; set; } 26 | 27 | [JsonProperty("deductionCurrency", NullValueHandling = NullValueHandling.Ignore)] 28 | public string DeductionCurrency { get; set; } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/SubUserTradableMarketResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class SubUserTradableMarketResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public TradableMarket[] Data; 15 | 16 | public class TradableMarket 17 | { 18 | [JsonProperty("subUid", NullValueHandling = NullValueHandling.Ignore)] 19 | public string SubUid; 20 | 21 | [JsonProperty("accountType", NullValueHandling = NullValueHandling.Ignore)] 22 | public string AccountType; 23 | 24 | [JsonProperty("activation", NullValueHandling = NullValueHandling.Ignore)] 25 | public string Activation; 26 | 27 | [JsonProperty("errCode", NullValueHandling = NullValueHandling.Ignore)] 28 | public int ErrCode; 29 | 30 | [JsonProperty("errMessage", NullValueHandling = NullValueHandling.Ignore)] 31 | public string ErrMessage; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/SubUserApiKeyGenerationResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class SubUserApiKeyGenerationResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public ApiKeyGeneration Data; 15 | 16 | public class ApiKeyGeneration 17 | { 18 | [JsonProperty("note", NullValueHandling = NullValueHandling.Ignore)] 19 | public string Note; 20 | 21 | [JsonProperty("accessKey", NullValueHandling = NullValueHandling.Ignore)] 22 | public string AccessKey; 23 | 24 | [JsonProperty("secretKey", NullValueHandling = NullValueHandling.Ignore)] 25 | public string SecretKey; 26 | 27 | [JsonProperty("permission", NullValueHandling = NullValueHandling.Ignore)] 28 | public string Permission; 29 | 30 | [JsonProperty("ipAddresses", NullValueHandling = NullValueHandling.Ignore)] 31 | public string IpAddresses; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/SubUserTransferabilityResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class SubUserTransferabilityResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public Transferability[] Data; 15 | 16 | public class Transferability 17 | { 18 | [JsonProperty("subUid", NullValueHandling = NullValueHandling.Ignore)] 19 | public long SubUid; 20 | 21 | [JsonProperty("accountType", NullValueHandling = NullValueHandling.Ignore)] 22 | public string AccountType; 23 | 24 | [JsonProperty("transferrable", NullValueHandling = NullValueHandling.Ignore)] 25 | public bool Transferrable; 26 | 27 | [JsonProperty("errCode", NullValueHandling = NullValueHandling.Ignore)] 28 | public int ErrCode; 29 | 30 | [JsonProperty("errMessage", NullValueHandling = NullValueHandling.Ignore)] 31 | public string ErrMessage; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeMarketByPriceResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | /// 6 | /// SubscribeMarketByPrice response 7 | /// 8 | public class SubscribeMarketByPriceResponse : WebSocketResponseBase 9 | { 10 | /// 11 | /// Response body from req 12 | /// 13 | public Tick data; 14 | 15 | /// 16 | /// Response body from sub 17 | /// 18 | public Tick tick; 19 | 20 | public class Tick 21 | { 22 | /// 23 | /// Sequence number of the message 24 | /// 25 | public long seqNum; 26 | 27 | /// 28 | /// Sequence number of previous message 29 | /// 30 | public long prevSeqNum; 31 | 32 | /// 33 | /// The current all bids in format [price, quote volume] 34 | /// 35 | public float[][] bids; 36 | 37 | /// 38 | /// The current all asks in format [price, quote volume] 39 | /// 40 | public float[][] asks; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/AlgoOrder/GetOpenOrdersResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.AlgoOrder 2 | { 3 | public class GetOpenOrdersResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data[] data; 19 | 20 | public class Data 21 | { 22 | public int accountId; 23 | 24 | public string source; 25 | 26 | public string clientOrderId; 27 | 28 | public string symbol; 29 | 30 | public string orderPrice; 31 | 32 | public string orderSize; 33 | 34 | public string orderValue; 35 | 36 | public string orderSide; 37 | 38 | public string timeInForce; 39 | 40 | public string orderType; 41 | 42 | public string stopPrice; 43 | 44 | public string trailingRate; 45 | 46 | public long orderOrigTime; 47 | 48 | public long lastActTime; 49 | 50 | public string orderStatus; 51 | } 52 | 53 | public long nextId; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeBestBidOfferResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | /// 6 | /// SubscribeBestBidOffer response 7 | /// 8 | public class SubscribeBestBidOfferResponse : WebSocketResponseBase 9 | { 10 | /// 11 | /// Response body from sub 12 | /// 13 | public Tick tick; 14 | 15 | public class Tick 16 | { 17 | /// 18 | /// Quote timestamp in millionsecond 19 | /// 20 | public long quoteTime; 21 | 22 | /// 23 | /// Trading symbol 24 | /// 25 | public string symbol; 26 | 27 | /// 28 | /// Best bid 29 | /// 30 | public float bid; 31 | 32 | /// 33 | /// Best bid size 34 | /// 35 | public float bidSize; 36 | 37 | /// 38 | /// Best ask 39 | /// 40 | public float ask; 41 | 42 | /// 43 | /// Best ask size 44 | /// 45 | public float askSize; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Wallet/GetDepositAddressResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Wallet 2 | { 3 | /// 4 | /// GetDepositAddress response 5 | /// 6 | public class GetDepositAddressResponse 7 | { 8 | /// 9 | /// Status code 10 | /// 11 | public int code; 12 | 13 | /// 14 | /// Error message (if any) 15 | /// 16 | public string message; 17 | 18 | /// 19 | /// Response body 20 | /// 21 | public Address[] data; 22 | 23 | /// 24 | /// Deposit address 25 | /// 26 | public class Address 27 | { 28 | /// 29 | /// Crypto currency 30 | /// 31 | public string currency; 32 | 33 | /// 34 | /// Deposit address 35 | /// 36 | public string address; 37 | 38 | /// 39 | /// Deposit address tag 40 | /// 41 | public string addressTag; 42 | 43 | /// 44 | /// Blockchain name 45 | /// 46 | public string chain; 47 | 48 | public string note; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountInfoResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Account 2 | { 3 | /// 4 | /// GetAccountInfo response 5 | /// 6 | public class GetAccountInfoResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// Response body 15 | /// 16 | public AccountInfo[] data; 17 | 18 | /// 19 | /// Account info 20 | /// 21 | public class AccountInfo 22 | { 23 | /// 24 | /// Unique account id 25 | /// 26 | public int id; 27 | 28 | /// 29 | /// The type of this account 30 | /// Possible values: [spot, margin, otc, point, super-margin] 31 | /// 32 | public string type; 33 | 34 | /// 35 | /// The type of sub account (applicable only for isolated margin accout) 36 | /// 37 | public string subtype; 38 | 39 | /// 40 | /// Account state 41 | /// Possible values: [working, lock] 42 | /// 43 | public string state; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Wallet/GetWithdrawAddressResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Wallet 2 | { 3 | public class GetWithdrawAddressResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Address[] data; 19 | 20 | /// 21 | /// Deposit address 22 | /// 23 | public class Address 24 | { 25 | /// 26 | /// Crypto currency 27 | /// 28 | public string currency; 29 | 30 | /// 31 | /// Blockchain name 32 | /// 33 | public string chain; 34 | 35 | /// 36 | /// Deposit address 37 | /// 38 | public string address; 39 | 40 | /// 41 | /// Deposit address tag 42 | /// 43 | public string addressTag; 44 | 45 | /// 46 | /// The address note 47 | /// 48 | public string note; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/OrderWebSocketClient/RequestOrdersWebSocketV1Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Model.Response.Order; 3 | using Huobi.SDK.Model.Request.Order; 4 | using Huobi.SDK.Core.Log; 5 | 6 | namespace Huobi.SDK.Core.Client 7 | { 8 | /// 9 | /// Responsible to handle orders request from WebSocket 10 | /// This need authentication version 1 11 | /// 12 | public class RequestOrdersWebSocketV1Client : WebSocketV1ClientBase 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// API Access Key 18 | /// API Secret Key 19 | /// API Host 20 | public RequestOrdersWebSocketV1Client(string accessKey, string secretKey, string host = DEFAULT_HOST) 21 | : base(accessKey, secretKey, host) 22 | { 23 | } 24 | 25 | /// 26 | /// Search past and open orders based on searching criteria. 27 | /// 28 | /// request 29 | public void Request(RequestOrdersRequest request) 30 | { 31 | _WebSocket.Send(request.ToJson()); 32 | 33 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={request.topic}, accountId={request.AccountId} symbol={request.symbol}"); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/AccountWebSocketClient/RequestAccountWebSocketV1Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Account; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle account asset request from WebSocket 9 | /// This need authentication version 1 10 | /// 11 | public class RequestAccountWebSocketV1ClientV : WebSocketV1ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public RequestAccountWebSocketV1ClientV(string accessKey, string secretKey, string host = DEFAULT_HOST) 20 | :base(accessKey, secretKey, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Request all account data of the current user. 26 | /// 27 | /// Client id 28 | public void Request(string clientId = "") 29 | { 30 | string topic = "accounts.list"; 31 | 32 | _WebSocket.Send($"{{ \"op\":\"req\", \"cid\":\"{clientId}\", \"topic\": \"{topic}\" }}"); 33 | 34 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/AlgoOrder/GetSpecificOrderResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.AlgoOrder 2 | { 3 | public class GetSpecificOrderResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data data; 19 | 20 | public class Data 21 | { 22 | public int accountId; 23 | 24 | public string source; 25 | 26 | public string clientOrderId; 27 | 28 | public string orderId; 29 | 30 | public string symbol; 31 | 32 | public string orderPrice; 33 | 34 | public string orderSize; 35 | 36 | public string orderValue; 37 | 38 | public string orderSide; 39 | 40 | public string timeInForce; 41 | 42 | public string orderType; 43 | 44 | public string stopPrice; 45 | 46 | public string trailingRate; 47 | 48 | public long orderOrigTime; 49 | 50 | public long lastActTime; 51 | 52 | public long orderCreateTime; 53 | 54 | public string orderStatus; 55 | 56 | public int errCode; 57 | 58 | public string errMessage; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/AlgoOrder/GetHistoryOrdersResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.AlgoOrder 2 | { 3 | public class GetHistoryOrdersResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Data[] data; 19 | 20 | public class Data 21 | { 22 | public int accountId; 23 | 24 | public string source; 25 | 26 | public string clientOrderId; 27 | 28 | public string orderId; 29 | 30 | public string symbol; 31 | 32 | public string orderPrice; 33 | 34 | public string orderSize; 35 | 36 | public string orderValue; 37 | 38 | public string orderSide; 39 | 40 | public string timeInForce; 41 | 42 | public string orderType; 43 | 44 | public string stopPrice; 45 | 46 | public string trailingRate; 47 | 48 | public long orderOrigTime; 49 | 50 | public long lastActTime; 51 | 52 | public long orderCreateTime; 53 | 54 | public string orderStatus; 55 | 56 | public int errCode; 57 | 58 | public string errMessage; 59 | } 60 | 61 | public long nextId; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/StableCoin/ExchangeStableCoinResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.StableCoin 4 | { 5 | /// 6 | /// ExchangeStableCoin response 7 | /// 8 | public class ExchangeStableCoinResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public Data data; 20 | 21 | public class Data 22 | { 23 | [JsonProperty("transact-id")] 24 | public long transactId; 25 | 26 | public string currency; 27 | 28 | public string amount; 29 | 30 | public string type; 31 | 32 | [JsonProperty("exchange-amount")] 33 | public string exchangeAmount; 34 | 35 | [JsonProperty("exchange-fee")] 36 | public string exchangeFee; 37 | 38 | public long time; 39 | } 40 | 41 | /// 42 | /// Error code 43 | /// 44 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 45 | public string errorCode; 46 | 47 | /// 48 | /// Error message 49 | /// 50 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 51 | public string errorMessage; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/GetTransactFeeRate.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Order 2 | { 3 | public class GetTransactFeeRateResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Fee[] data; 19 | 20 | public class Fee 21 | { 22 | /// 23 | /// Trading symbol 24 | /// 25 | public string symbol; 26 | 27 | /// 28 | /// Basic fee rate - passive side 29 | /// 30 | public string makerFeeRate; 31 | 32 | /// 33 | /// Basic fee rate - aggressive side 34 | /// 35 | public string takerFeeRate; 36 | 37 | /// 38 | /// Deducted fee rate – passive side. 39 | /// If deduction is inapplicable or disabled, return basic fee rate 40 | /// 41 | public string actualMakerRate; 42 | 43 | /// 44 | /// Deducted fee rate – aggressive side. 45 | /// If deduction is inapplicable or disabled, return basic fee rate. 46 | /// 47 | public string actualTakerRate; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/OrderWebSocketClient/RequestOrderWebSocketV1Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Order; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle order request from WebSocket 9 | /// This need authentication version 1 10 | /// 11 | public class RequestOrderWebSocketV1Client : WebSocketV1ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public RequestOrderWebSocketV1Client(string accessKey, string secretKey, string host = DEFAULT_HOST) 20 | : base(accessKey, secretKey, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Get order details by a given order ID. 26 | /// 27 | /// Order id 28 | /// Client id 29 | public void Request(string orderId, string clientId = "") 30 | { 31 | string topic = "orders.detail"; 32 | 33 | _WebSocket.Send($"{{ \"op\":\"req\", \"cid\": \"{clientId}\", \"topic\":\"{topic}\", \"order-id\":\"{orderId}\" }}"); 34 | 35 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}, orderId={orderId}"); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/RequestBuilder/SignerTest.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.RequestBuilder; 2 | using Xunit; 3 | 4 | namespace Huobi.SDK.Core.Test.RequestBuilder 5 | { 6 | public class SignatureTest 7 | { 8 | [Fact] 9 | public void Sign_FourString_Success() 10 | { 11 | var signer = new Signer("12345-67890-12345-67890"); 12 | 13 | string result = signer.Sign( 14 | "GET", 15 | "api.huobi.pro", 16 | "/v1/account/accounts", 17 | "AccessKeyId=abcdefg-hijklmn-opqrst-uvwxyz&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-04-01T12%3A34%3A56"); 18 | 19 | Assert.Equal("3IUZcEak4IIRrh7/idFrP2Jj77MaWGXR/oQbe9gL4+I=", result); 20 | } 21 | 22 | [Fact] 23 | public void Sign_RunTwice_ReturnSameResult() 24 | { 25 | var signer = new Signer("secret"); 26 | 27 | string result1 = signer.Sign("GET", "api.huobi.pro", "/v1/account/history", "account-id=1¤cy=btcusdt"); 28 | string result2 = signer.Sign("GET", "api.huobi.pro", "/v1/account/history", "account-id=1¤cy=btcusdt"); 29 | 30 | Assert.Equal(result1, result2); 31 | } 32 | 33 | [Fact] 34 | public void Sign_OneNullStringThreeString_ReturnEmpty() 35 | { 36 | var signer = new Signer("secret"); 37 | 38 | string result = signer.Sign("GET", "api.huob.pro", "", "account-id=1¤cy=btcusdt"); 39 | 40 | Assert.Equal("", result); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/GetDepthResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Market 2 | { 3 | /// 4 | /// GetDepth response 5 | /// 6 | public class GetDepthResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// The data stream 15 | /// 16 | public string ch; 17 | 18 | /// 19 | /// The timestamp (millisecond) when API respond 20 | /// 21 | public long ts; 22 | 23 | /// 24 | /// The response body 25 | /// 26 | public tickData tick; 27 | 28 | /// 29 | /// The tick data 30 | /// 31 | public class tickData 32 | { 33 | /// 34 | /// The UNIX timestamp in milliseconds adjusted to Singapore time 35 | /// 36 | public long ts; 37 | 38 | /// 39 | /// The internal data 40 | /// 41 | public float version; 42 | 43 | /// 44 | /// The current all ask in format [price, quote volume] 45 | /// 46 | public float[][] asks; 47 | 48 | /// 49 | /// The current all bit in format [price, quote volume] 50 | /// 51 | public float[][] bids; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/AppLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.Log; 3 | 4 | namespace Huobi.SDK.Example 5 | { 6 | public class AppLogger 7 | { 8 | private static readonly ILogger _logger = new ConsoleLogger(); 9 | 10 | public static void Trace(string message) 11 | { 12 | _logger.Log(LogLevel.Trace, message); 13 | } 14 | 15 | public static void Debug(string message) 16 | { 17 | _logger.Log(LogLevel.Debug, message); 18 | } 19 | 20 | public static void Info(string message) 21 | { 22 | _logger.Log(LogLevel.Info, message); 23 | } 24 | 25 | public static void Warn(string message) 26 | { 27 | _logger.Log(LogLevel.Warn, message); 28 | } 29 | 30 | public static void Error(string message, Exception exception = null) 31 | { 32 | if (exception == null) 33 | { 34 | _logger.Log(LogLevel.Error, message); 35 | } 36 | else 37 | { 38 | _logger.Log(LogLevel.Error, message + exception.StackTrace); 39 | } 40 | } 41 | 42 | public static void Fatal(string message, Exception exception = null) 43 | { 44 | if (exception == null) 45 | { 46 | _logger.Log(LogLevel.Fatal, message); 47 | } 48 | else 49 | { 50 | _logger.Log(LogLevel.Fatal, message + exception.StackTrace); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeTradeResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | /// 6 | /// SubscribeTrade response 7 | /// 8 | public class SubscribeTradeResponse : WebSocketResponseBase 9 | { 10 | /// 11 | /// Response body from req 12 | /// 13 | public Trade[] data; 14 | 15 | /// 16 | /// Response body from sub 17 | /// 18 | public Tick tick; 19 | 20 | public class Tick 21 | { 22 | public long id; 23 | 24 | public string ts; 25 | 26 | public Trade[] data; 27 | } 28 | 29 | public class Trade 30 | { 31 | /// 32 | /// Unique trade id (NEW) 33 | /// 34 | public long tradeid; 35 | 36 | /// 37 | /// Last trade volume 38 | /// 39 | public float amount; 40 | 41 | /// 42 | /// Last trade price 43 | /// 44 | public float price; 45 | 46 | /// 47 | /// Last trade timestamp in millisecond) 48 | /// 49 | public long ts; 50 | 51 | /// 52 | /// Aggressive order side (taker's order side) of the trade 53 | /// Possible values: [buy, sell] 54 | /// 55 | public string direction; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/Program.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Log; 2 | 3 | namespace Huobi.SDK.Example 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | AppLogger.Info("Example started"); 10 | 11 | Config.LoadConfig(); 12 | 13 | RullAllExamples(); 14 | 15 | AppLogger.Info("Example stopped"); 16 | } 17 | 18 | static void RullAllExamples() 19 | { 20 | RunAllRestExamples(); 21 | 22 | // RunAllWebSocketExamples(); 23 | } 24 | 25 | static void RunPerformanceTest() 26 | { 27 | PerformanceLogger.GetInstance().Enable(true); 28 | 29 | RunAllRestExamples(); 30 | } 31 | 32 | static void RunAllRestExamples() 33 | { 34 | // CommonClientExample.RunAll(); 35 | 36 | // MarketClientExample.RunAll(); 37 | 38 | AccountClientExample.RunAll(); 39 | 40 | // WalletClientExample.RunAll(); 41 | 42 | // SubUserClientExample.RunAll(); 43 | 44 | // OrderClientExample.RunAll(); 45 | 46 | // IsolatedMarginClientExample.RunAll(); 47 | 48 | // CrossMarginClientExample.RunAll(); 49 | 50 | // StableCoinClientExample.RunAll(); 51 | 52 | // ETFClientExample.RunAll(); 53 | } 54 | 55 | static void RunAllWebSocketExamples() 56 | { 57 | MarketWebSocketClientExample.RunAll(); 58 | 59 | AccountWebSocketClientExample.RunAll(); 60 | 61 | OrderWebSocketClientExample.RunAll(); 62 | 63 | } 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/GetFeeResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Huobi.SDK.Model.Response.Order 5 | { 6 | /// 7 | /// GetFee response 8 | /// 9 | [Obsolete] 10 | public class GetFeeResponse 11 | { 12 | /// 13 | /// Response status 14 | /// 15 | public string status; 16 | 17 | /// 18 | /// Error code 19 | /// 20 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 21 | public string errorCode; 22 | 23 | /// 24 | /// Error message 25 | /// 26 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 27 | public string errorMessage; 28 | 29 | /// 30 | /// Response body 31 | /// 32 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 33 | public Fee[] data; 34 | 35 | /// 36 | /// Match result of an order 37 | /// 38 | public class Fee 39 | { 40 | /// 41 | /// Trading symbol 42 | /// 43 | public string symbol; 44 | 45 | /// 46 | /// Maker fee rate 47 | /// 48 | [JsonProperty("maker-fee")] 49 | public string makerFee; 50 | 51 | /// 52 | /// Taker fee rate 53 | /// 54 | [JsonProperty("taker-fee")] 55 | public string takerFee; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/RequestBuilder/SignerED25519Test.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.RequestBuilder; 2 | using Xunit; 3 | 4 | namespace Huobi.SDK.Core.Test.RequestBuilder 5 | { 6 | public class Ed25519SignerTest 7 | { 8 | private const string PrivateKey = "MC4CAQAwBQYDK2VwBCIEILHeu7fAq16wUfz/w91bQVEQO+J1dJ6HE4YGdyfYMPqt"; // 替换为有效的私钥 9 | 10 | [Fact] 11 | public void Sign_FourString_Success() 12 | { 13 | var signer = new Ed25519Signer(PrivateKey); 14 | string result = signer.Sign( 15 | "GET", 16 | "https://api.huobi.pro/v1/account/accounts?AccessKeyId=abcdefg-hijklmn-opqrst-uvwxyz&SignatureMethod=ED25519&SignatureVersion=2&Timestamp=2020-04-01T12%3A34%3A56" 17 | ); 18 | 19 | Assert.Equal("expected_base64_encoded_signature", result); // 替换为您预期的签名 20 | } 21 | 22 | [Fact] 23 | public void Sign_RunTwice_ReturnSameResult() 24 | { 25 | var signer = new Ed25519Signer(PrivateKey); 26 | 27 | string result1 = signer.Sign("GET", "https://api.huobi.pro/v1/account/history?account-id=1¤cy=btcusdt"); 28 | string result2 = signer.Sign("GET", "https://api.huobi.pro/v1/account/history?account-id=1¤cy=btcusdt"); 29 | 30 | Assert.Equal(result1, result2); 31 | } 32 | 33 | [Fact] 34 | public void Sign_OneNullStringThreeString_ReturnEmpty() 35 | { 36 | var signer = new Ed25519Signer(PrivateKey); 37 | 38 | string result = signer.Sign("GET", "https://api.huobi.pro", "", "account-id=currency=btcusdt"); 39 | 40 | Assert.Equal("", result); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Request/Order/AutoPlaceRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Request.Order 4 | { 5 | public class AutoPlaceRequest 6 | { 7 | [JsonProperty("symbol", NullValueHandling = NullValueHandling.Ignore)] 8 | public string Symbol; 9 | 10 | [JsonProperty("account-id", NullValueHandling = NullValueHandling.Ignore)] 11 | public string AccountId; 12 | 13 | [JsonProperty("amount", NullValueHandling = NullValueHandling.Ignore)] 14 | public string Amount; 15 | 16 | [JsonProperty("market-amount", NullValueHandling = NullValueHandling.Ignore)] 17 | public string MarketAmount; 18 | 19 | [JsonProperty("borrow-amount", NullValueHandling = NullValueHandling.Ignore)] 20 | public string BorrowAmount; 21 | 22 | [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] 23 | public string Type; 24 | 25 | [JsonProperty("trade-purpose", NullValueHandling = NullValueHandling.Ignore)] 26 | public string TradePurpose; 27 | 28 | [JsonProperty("price", NullValueHandling = NullValueHandling.Ignore)] 29 | public string Price; 30 | 31 | [JsonProperty("stop-price", NullValueHandling = NullValueHandling.Ignore)] 32 | public string StopPrice; 33 | 34 | [JsonProperty("operator", NullValueHandling = NullValueHandling.Ignore)] 35 | public string Operator; 36 | 37 | [JsonProperty("source", NullValueHandling = NullValueHandling.Ignore)] 38 | public string Source; 39 | 40 | public string ToJson() 41 | { 42 | return JsonConvert.SerializeObject(this); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserApiKeyResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class GetSubUserApiKeyResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public APIKeyData[] Data; 15 | 16 | public class APIKeyData 17 | { 18 | [JsonProperty("accessKey", NullValueHandling = NullValueHandling.Ignore)] 19 | public string AccessKey; 20 | 21 | [JsonProperty("note", NullValueHandling = NullValueHandling.Ignore)] 22 | public string Note; 23 | 24 | [JsonProperty("permission", NullValueHandling = NullValueHandling.Ignore)] 25 | public string Permission; 26 | 27 | [JsonProperty("ipAddresses", NullValueHandling = NullValueHandling.Ignore)] 28 | public string IPAddresses; 29 | 30 | [JsonProperty("validDays", NullValueHandling = NullValueHandling.Ignore)] 31 | public int ValidDays; 32 | 33 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 34 | public string Status; 35 | 36 | [JsonProperty("createTime", NullValueHandling = NullValueHandling.Ignore)] 37 | public long CreateTime; 38 | 39 | [JsonProperty("updateTime", NullValueHandling = NullValueHandling.Ignore)] 40 | public long UpdateTime; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/RequestBuilder/WebSocketRequestBuilderTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.Model; 3 | using Huobi.SDK.Core.RequestBuilder; 4 | using Newtonsoft.Json; 5 | using Xunit; 6 | 7 | namespace Huobi.SDK.Core.Test.RequestBuilder 8 | { 9 | public class WebSocketRequestBuilderTest 10 | { 11 | [Fact] 12 | public void Build_NullParam_Success() 13 | { 14 | var builder = new WebSocketV1RequestBuilder("access", "secret", "api.huobi.pro","256" ,"/ws/v1"); 15 | 16 | string auth = builder.Build(); 17 | 18 | var authReq = JsonConvert.DeserializeObject(auth); 19 | 20 | Assert.Equal("auth", authReq.op); 21 | Assert.Equal("access", authReq.AccessKeyId); 22 | Assert.Equal("HmacSHA256", authReq.SignatureMethod); 23 | Assert.Equal("2", authReq.SignatureVersion); 24 | } 25 | 26 | [Fact] 27 | public void Build_Time_Success() 28 | { 29 | var builder = new WebSocketV1RequestBuilder("access", "secret", "api.huobi.pro", "256","/ws/v1"); 30 | 31 | var utcTime = new DateTime(2019, 11, 21, 10, 0, 0); 32 | string auth = builder.Build(utcTime); 33 | 34 | var authReq = JsonConvert.DeserializeObject(auth); 35 | 36 | Assert.Equal("auth", authReq.op); 37 | Assert.Equal("access", authReq.AccessKeyId); 38 | Assert.Equal("HmacSHA256", authReq.SignatureMethod); 39 | Assert.Equal("2", authReq.SignatureVersion); 40 | Assert.Equal(utcTime.ToString("s"), authReq.Timestamp); 41 | Assert.Equal("nWj8xkaQ8mWPyvdtRVPFkrX2B8v3mSomAfhXiOGoS3M=", authReq.Signature); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/CancelOrdersByCriteriaResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// CancelOrdersByCriteria response 7 | /// 8 | public class CancelOrdersByCriteriaResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Error code 17 | /// 18 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 19 | public string errorCode; 20 | 21 | /// 22 | /// Error message 23 | /// 24 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorMessage; 26 | 27 | /// 28 | /// Response body 29 | /// 30 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 31 | public Body data; 32 | 33 | /// 34 | /// Response body 35 | /// 36 | public class Body 37 | { 38 | /// 39 | /// The number of cancel request sent successfully 40 | /// 41 | [JsonProperty("success-count")] 42 | public int successCount; 43 | 44 | /// 45 | /// The number of cancel request failed 46 | /// 47 | [JsonProperty("failed-count")] 48 | public int failedCount; 49 | 50 | /// 51 | /// The next order id that can be cancelled 52 | /// 53 | [JsonProperty("next-id")] 54 | public int nextId; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/RequestAccountResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | using Newtonsoft.Json; 3 | 4 | namespace Huobi.SDK.Model.Response.Account 5 | { 6 | /// 7 | /// RequestAccount response 8 | /// 9 | public class RequestAccountResponse : WebSocketV1ResponseBase 10 | { 11 | /// 12 | /// Response body from sub 13 | /// 14 | public AccountBalance[] data; 15 | 16 | public class AccountBalance 17 | { 18 | 19 | /// 20 | /// Account id 21 | /// 22 | public int id; 23 | 24 | /// 25 | /// Account type 26 | /// 27 | public string type; 28 | 29 | /// 30 | /// Account staus 31 | /// 32 | public string state; 33 | 34 | /// 35 | /// The list of account balance 36 | /// 37 | public Balance[] list; 38 | 39 | /// 40 | /// Account balance 41 | /// 42 | public class Balance 43 | { 44 | 45 | /// 46 | /// sub-account currency 47 | /// 48 | public string currency; 49 | 50 | /// 51 | /// sub-account type 52 | /// Possible values: [including trade, loan, interest] 53 | /// 54 | public string type; 55 | 56 | /// 57 | /// sub-account balance 58 | /// 59 | public string balance; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/RequestBuilder/PrivateUrlBuilderTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.RequestBuilder; 3 | using Xunit; 4 | 5 | namespace Huobi.SDK.Core.Test.RequestBuilder 6 | { 7 | public class PrivateUrlBuilderTest 8 | { 9 | [Fact] 10 | public void Build_NoRequestParameter_Success() 11 | { 12 | var builder = new PrivateUrlBuilder("abcdefg-hijklmn-opqrst-uvwxyz", "12345-67890-12345-67890", "api.huobi.pro","256"); 13 | DateTime dateTime = new DateTime(2020, 04, 01, 12, 34, 56); 14 | 15 | string result = builder.Build("GET", "/v1/account/accounts", dateTime); 16 | 17 | string expected = @"https://api.huobi.pro/v1/account/accounts?AccessKeyId=abcdefg-hijklmn-opqrst-uvwxyz&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-04-01T12%3A34%3A56&Signature=3IUZcEak4IIRrh7%2FidFrP2Jj77MaWGXR%2FoQbe9gL4%2BI%3D"; 18 | Assert.Equal(expected, result); 19 | } 20 | 21 | [Fact] 22 | public void Build_RequestParameter_Success() 23 | { 24 | var builder = new PrivateUrlBuilder("access", "secret", "api.huobi.pro","256"); 25 | DateTime dateTime = new DateTime(2019, 11, 21, 10, 0, 0); 26 | var request = new GetRequest() 27 | .AddParam("account-id", "123") 28 | .AddParam("currency", "btc"); 29 | 30 | 31 | string result = builder.Build("GET", "/v1/account/history", dateTime, request); 32 | 33 | 34 | string escapedTime = Uri.EscapeDataString(dateTime.ToString("s")); 35 | string expected = string.Format(@"https://api.huobi.pro/v1/account/history?AccessKeyId=access&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp={0}&account-id=123¤cy=btc&Signature=SGZYJ9Ub%2FhFerEBbSWsCxl8Djk%2BLRBgEZOB4fLc4T9Q%3D", 36 | escapedTime); 37 | Assert.Equal(expected, result); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Common/GetMarketStatusResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Common 2 | { 3 | public class GetMarketStatusResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Error message (if any) 12 | /// 13 | public string message; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Status data; 19 | 20 | public class Status 21 | { 22 | /// 23 | /// Market status (1=normal, 2=halted, 3=cancel-only) 24 | /// 25 | public int marketStatus; 26 | 27 | /// 28 | /// Halt start time (unix time in millisecond) , only valid for marketStatus=halted or cancel-only 29 | /// 30 | public long haltStartTime; 31 | 32 | /// 33 | /// Estimated halt end time (unix time in millisecond) , only valid for marketStatus=halted or cancel-only; 34 | /// if this field is not returned during marketStatus=halted or cancel-only, 35 | /// it implicates the halt end time cannot be estimated at this time. 36 | /// 37 | public long haltEndTime; 38 | 39 | /// 40 | /// Halt reason (2=emergency-maintenance, 3=scheduled-maintenance) , only valid for marketStatus=halted or cancel-only 41 | /// 42 | public int haltReason; 43 | 44 | /// 45 | /// Affected symbols, separated by comma. If affect all symbols just respond with value ‘all’. 46 | /// Only valid for marketStatus=halted or cancel-only 47 | /// 48 | public string affectedSmbols; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetPointBalanceResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | public class GetPointBalanceResponse 6 | { 7 | /// 8 | /// Status code 9 | /// 10 | public int code; 11 | 12 | /// 13 | /// Error message (if any) 14 | /// 15 | public string message; 16 | 17 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 18 | public string success; 19 | 20 | /// 21 | /// Response body 22 | /// 23 | public Data data; 24 | 25 | public class Data 26 | { 27 | /// 28 | /// Account ID 29 | /// 30 | public string accountId; 31 | 32 | /// 33 | /// Account status (working, lock, fl-sys, fl-mgt, fl-end, fl-negative) 34 | /// 35 | public string accountStatus; 36 | 37 | /// 38 | /// Account balance 39 | /// 40 | public string acctBalance; 41 | 42 | public GroupId[] groupIds; 43 | 44 | public class GroupId 45 | { 46 | /// 47 | /// Group ID 48 | /// 49 | public long groupId; 50 | 51 | /// 52 | /// Expiration date (unix time in millisecond) 53 | /// 54 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 55 | public long expiryDate; 56 | 57 | /// 58 | /// Remaining amount 59 | /// 60 | public string remainAmt; 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/MarketWebSocketClient/BestBidOfferWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Market; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle BBO data from WebSocket 9 | /// 10 | public class BestBidOfferWebSocketClient : WebSocketClientBase 11 | { 12 | 13 | /// 14 | /// Constructor 15 | /// 16 | /// websockethost 17 | public BestBidOfferWebSocketClient(string host = DEFAULT_HOST) 18 | :base(host) 19 | { 20 | } 21 | 22 | /// 23 | /// Subscribe latest market by price order book in snapshot mode at 1-second interval. 24 | /// 25 | /// Trading symbol 26 | /// Client id 27 | public void Subscribe(string symbol, string clientId = "") 28 | { 29 | string topic = $"market.{symbol}.bbo"; 30 | 31 | _WebSocket.Send($"{{\"sub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 32 | 33 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 34 | } 35 | 36 | /// 37 | /// Unsubscribe market by price order book 38 | /// 39 | /// Trading symbol 40 | /// Client id 41 | public void UnSubscribe(string symbol, string clientId = "") 42 | { 43 | string topic = $"market.{symbol}.bbo"; 44 | 45 | _WebSocket.Send($"{{\"unsub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 46 | 47 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}, clientId={clientId}"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/Config.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | namespace Huobi.SDK.Example 4 | { 5 | public class Config 6 | { 7 | // The shared keys and ids that used for all the examples 8 | public static string Host { get; private set; } 9 | public static string AccessKey { get; private set; } 10 | public static string PublicKey { get; private set; } 11 | public static string PrivateKey { get; private set; } 12 | public static string SecretKey { get; private set; } 13 | public static string AccountId { get; private set; } 14 | public static string SubUserId { get; private set; } 15 | public static string Sign { get; private set; } 16 | 17 | /// 18 | /// Load Accesskey and AccountId from 'appsettings.json' and SecretKey from 'key.json'. 19 | /// 20 | /// To prevent submitting SecretKey into repository by accident, the 'key.json' file 21 | /// is already added in the .gitignore file 22 | /// 23 | /// You should create the key.json file and include it into your solution with below definition 24 | /// 25 | /// { 26 | /// "SecretKey": "xxxx-xxxx-xxxx-xxxx" 27 | /// } 28 | /// 29 | /// 30 | public static void LoadConfig() 31 | { 32 | // Read configs from 'appsettings.json' 33 | var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); 34 | Host = config["Host"]; 35 | AccessKey = config["AccessKey"]; 36 | AccountId = config["AccountId"]; 37 | SubUserId = config["SubUserId"]; 38 | Sign=config["Sign"]; 39 | PrivateKey=config["PrivateKey"]; 40 | PublicKey=config["PublicKey"]; 41 | 42 | // Read SecretKey from 'key.json' 43 | config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); 44 | SecretKey = config["SecretKey"]; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeCandlestickResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | /// 6 | /// SubscribeCandlestick response 7 | /// 8 | public class SubscribeCandlestickResponse : WebSocketResponseBase 9 | { 10 | /// 11 | /// Response body from req 12 | /// 13 | public Tick[] data; 14 | 15 | /// 16 | /// Response body from sub 17 | /// 18 | public Tick tick; 19 | 20 | /// 21 | /// Candlestick 22 | /// 23 | public class Tick 24 | { 25 | /// 26 | /// UNIX epoch timestamp in second as response id 27 | /// 28 | public long id; 29 | 30 | /// 31 | /// Aggregated trading volume during the interval (in base currency) 32 | /// 33 | public float amount; 34 | 35 | /// 36 | /// Number of trades during the interval 37 | /// 38 | public int count; 39 | 40 | /// 41 | /// Opening price during the interval 42 | /// 43 | public float open; 44 | 45 | /// 46 | /// Closing price during the interval 47 | /// 48 | public float close; 49 | 50 | /// 51 | /// Low price during the interval 52 | /// 53 | public float low; 54 | 55 | /// 56 | /// High price during the interval 57 | /// 58 | public float high; 59 | 60 | /// 61 | /// Aggregated trading value during the interval (in quote currency) 62 | /// 63 | public float vol; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/SubscribeAccountV2Response.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | /// 6 | /// SubscribeAccountV2 response 7 | /// 8 | public class SubscribeAccountV2Response : WebSocketV2ResponseBase 9 | { 10 | /// 11 | /// Response body from sub 12 | /// 13 | public AccountUpdate data; 14 | 15 | public class AccountUpdate 16 | { 17 | /// 18 | /// The crypto currency of this balance 19 | /// 20 | public string currency; 21 | 22 | /// 23 | /// The account id of this individual balance 24 | /// 25 | public int accountId; 26 | 27 | /// 28 | /// The account balance (only exists when account balance changed) 29 | /// 30 | public string balance; 31 | 32 | /// 33 | /// The available balance (only exists when available balance changed) 34 | /// 35 | public string available; 36 | 37 | /// 38 | /// Change type 39 | /// Possible values: [order-place,order-match,order-refund,order-cancel,order-fee-refund, 40 | /// margin-transfer,margin-loan,margin-interest,margin-repay,deposit, withdraw, other] 41 | /// 42 | public string changeType; 43 | 44 | /// 45 | /// Account type 46 | /// Possible values: [trade, frozen, loan, interest] 47 | /// 48 | public string accountType; 49 | 50 | /// 51 | /// Change timestamp in millisecond 52 | /// If it is null, then this message is account overview not update 53 | /// 54 | public long? changeTime; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Huobi.SDK.Core.Test/RequestBuilder/WebSocketRequestBuilderV2Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.Model; 3 | using Huobi.SDK.Core.RequestBuilder; 4 | using Newtonsoft.Json; 5 | using Xunit; 6 | 7 | namespace Huobi.SDK.Core.Test.RequestBuilder 8 | { 9 | public class WebSocketRequestBuilderV2Test 10 | { 11 | [Fact] 12 | public void Build_NullParam_Success() 13 | { 14 | var builder = new WebSocketV2RequestBuilder("access", "secret", "api.huobi.pro","256", "/ws/v2"); 15 | 16 | string auth = builder.Build(); 17 | 18 | var authReq = JsonConvert.DeserializeObject(auth); 19 | 20 | Assert.Equal("req", authReq.action); 21 | Assert.Equal("auth", authReq.ch); 22 | Assert.Equal("api", authReq.@params.authType); 23 | Assert.Equal("access", authReq.@params.accessKey); 24 | Assert.Equal("HmacSHA256", authReq.@params.signatureMethod); 25 | Assert.Equal("2.1", authReq.@params.signatureVersion); 26 | } 27 | 28 | [Fact] 29 | public void Build_Time_Success() 30 | { 31 | var builder = new WebSocketV2RequestBuilder("access", "secret", "api.huobi.pro","256", "/ws/v2"); 32 | 33 | DateTime utcTime = new DateTime(2019, 11, 21, 10, 0, 0); 34 | string auth = builder.Build(utcTime); 35 | 36 | var authReq = JsonConvert.DeserializeObject(auth); 37 | 38 | Assert.Equal("req", authReq.action); 39 | Assert.Equal("auth", authReq.ch); 40 | Assert.Equal("api", authReq.@params.authType); 41 | Assert.Equal("access", authReq.@params.accessKey); 42 | Assert.Equal("HmacSHA256", authReq.@params.signatureMethod); 43 | Assert.Equal("2.1", authReq.@params.signatureVersion); 44 | Assert.Equal(utcTime.ToString("s"), authReq.@params.timestamp); 45 | Assert.Equal("1/d+cUIEh4tC0aXho86zu5QAxVzJaTe56mUiB275T0E=", authReq.@params.signature); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/GetCandlestickResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Market 2 | { 3 | /// 4 | /// GetCandlestick response 5 | /// 6 | public class GetCandlestickResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// The data stream 15 | /// 16 | public string ch; 17 | 18 | /// 19 | /// The timestamp (millisecond) when API respond 20 | /// 21 | public long ts; 22 | 23 | /// 24 | /// Response body 25 | /// 26 | public Candlestick[] data; 27 | 28 | /// 29 | /// Candlestick detail 30 | /// 31 | public class Candlestick 32 | { 33 | /// 34 | /// Unix timestamp in seconds 35 | /// 36 | public int id; 37 | 38 | /// 39 | /// The aggregated trading volume in USDT 40 | /// 41 | public float amount; 42 | 43 | /// 44 | /// The number of completed trades 45 | /// 46 | public int count; 47 | 48 | /// 49 | /// The opening price 50 | /// 51 | public float open; 52 | 53 | /// 54 | /// The closing price 55 | /// 56 | public float close; 57 | 58 | /// 59 | /// The low price 60 | /// 61 | public float low; 62 | 63 | /// 64 | /// The high price 65 | /// 66 | public float high; 67 | 68 | /// 69 | /// The trading volume in base currency 70 | /// 71 | public float vol; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/StableCoin/GetStableCoinResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.StableCoin 4 | { 5 | public class GetStableCoinResponse 6 | { 7 | /// 8 | /// Response status 9 | /// 10 | public string status; 11 | 12 | /// 13 | /// Response body 14 | /// 15 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 16 | public Data data; 17 | 18 | public class Data 19 | { 20 | /// 21 | /// Stable coin name (PAX/USDC/TUSD) 22 | /// 23 | public string currency; 24 | 25 | /// 26 | /// Amount of stable coin to exchange 27 | /// 28 | public string amount; 29 | 30 | /// 31 | /// Type of the exchange (buy/sell) 32 | /// 33 | public string type; 34 | 35 | /// 36 | /// Amount of HUSD to exchange in or out 37 | /// 38 | public string exchangeAmount; 39 | 40 | /// 41 | /// Exchange fee (in HUSD) 42 | /// 43 | public string exchangeFee; 44 | 45 | /// 46 | /// Stable currency quoteID 47 | /// 48 | public string quoteId; 49 | 50 | /// 51 | /// Term of validity 52 | /// 53 | public string expiration; 54 | } 55 | 56 | /// 57 | /// Error code 58 | /// 59 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 60 | public string errorCode; 61 | 62 | /// 63 | /// Error message 64 | /// 65 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 66 | public string errorMessage; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/MarketWebSocketClient/MarketTickerWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Market; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle ticker data from WebSocket 9 | /// 10 | public class MarketTickerWebSocketClient : WebSocketClientBase 11 | { 12 | /// 13 | /// Constructor 14 | /// 15 | /// websockethost 16 | public MarketTickerWebSocketClient(string host = DEFAULT_HOST) 17 | :base(host) 18 | { 19 | } 20 | 21 | /// 22 | /// Request full Ticker data 23 | /// 24 | /// Trading symbol 25 | public void Req(string symbol) 26 | { 27 | string topic = $"market.{symbol}.ticker"; 28 | 29 | _WebSocket.Send($"{{\"req\": \"{topic}\"}}"); 30 | 31 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}"); 32 | } 33 | 34 | 35 | /// 36 | /// Subscribe Ticker 37 | /// 38 | /// Trading symbol 39 | public void Subscribe(string symbol) 40 | { 41 | string topic = $"market.{symbol}.ticker"; 42 | 43 | _WebSocket.Send($"{{\"sub\": \"market.{symbol}.ticker\"}}"); 44 | 45 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}"); 46 | } 47 | 48 | /// 49 | /// Unsubscribe ticker 50 | /// 51 | /// Trading symbol 52 | public void UnSubscribe(string symbol) 53 | { 54 | string topic = $"market.{symbol}.ticker"; 55 | 56 | _WebSocket.Send($"{{\"unsub\": \"market.{symbol}.ticker\"}}"); 57 | 58 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}"); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/PlaceOrdersResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// PlaceMultipleOrders response 7 | /// 8 | public class PlaceOrdersResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 19 | public PlaceOrderResult[] data; 20 | 21 | /// 22 | /// place order result 23 | /// 24 | public class PlaceOrderResult 25 | { 26 | /// 27 | /// The order id 28 | /// 29 | [JsonProperty("order-id")] 30 | public long orderId; 31 | 32 | /// 33 | /// The client order id (if any) 34 | /// 35 | [JsonProperty("client-order-id", NullValueHandling = NullValueHandling.Ignore)] 36 | public string clientOrderId; 37 | 38 | /// 39 | /// Error code for rejected order 40 | /// 41 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 42 | public string errorCode; 43 | 44 | /// 45 | /// Error message for rejected order 46 | /// 47 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 48 | public string errorMessage; 49 | } 50 | 51 | /// 52 | /// Error code 53 | /// 54 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 55 | public string errorCode; 56 | 57 | /// 58 | /// Error message 59 | /// 60 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 61 | public string errorMessage; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/SubscribeAccountV1Response.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | using Newtonsoft.Json; 3 | 4 | namespace Huobi.SDK.Model.Response.Account 5 | { 6 | /// 7 | /// SubscribeAccountV1 response 8 | /// 9 | public class SubscribeAccountV1Response : WebSocketV1ResponseBase 10 | { 11 | /// 12 | /// Response body from sub 13 | /// 14 | public AccountUpdate data; 15 | 16 | public class AccountUpdate 17 | { 18 | /// 19 | /// The event type which triggers this balance updates, 20 | /// Possible values: [oder.place, order.match, order.refund, order.cancel, order.fee-refund, deposit, withdraw 21 | /// (other balance transfer event types)] 22 | /// 23 | public string @event; 24 | 25 | /// 26 | /// The list of update detail 27 | /// 28 | public UpdateDetail[] list; 29 | 30 | /// 31 | /// Update detail 32 | /// 33 | public class UpdateDetail 34 | { 35 | /// 36 | /// The account id of this individual balance 37 | /// 38 | [JsonProperty("account-id")] 39 | public int accountId; 40 | 41 | /// 42 | /// The crypto currency of this balance 43 | /// 44 | public string currency; 45 | 46 | /// 47 | /// The type of this account 48 | /// Possible values: [including trade, loan, interest] 49 | /// 50 | public string type; 51 | 52 | /// 53 | /// The balance of this account, include frozen balance if "model" was set to 1 in subscription 54 | /// 55 | public string balance; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserAccountListResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | public class GetSubUserAccountListResponse 6 | { 7 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 8 | public int Code; 9 | 10 | [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] 11 | public string Message; 12 | 13 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 14 | public AccountList Data; 15 | 16 | public class AccountList 17 | { 18 | [JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)] 19 | public long Uid; 20 | 21 | [JsonProperty("deductMode", NullValueHandling = NullValueHandling.Ignore)] 22 | public object DeductMode; 23 | 24 | [JsonProperty("list", NullValueHandling = NullValueHandling.Ignore)] 25 | public ListObject[] List; 26 | } 27 | 28 | public class ListObject 29 | { 30 | [JsonProperty("accountType", NullValueHandling = NullValueHandling.Ignore)] 31 | public string AccountType; 32 | 33 | [JsonProperty("activation", NullValueHandling = NullValueHandling.Ignore)] 34 | public string Activation; 35 | 36 | [JsonProperty("transferrable", NullValueHandling = NullValueHandling.Ignore)] 37 | public bool Transferrable; 38 | 39 | [JsonProperty("accountIds", NullValueHandling = NullValueHandling.Ignore)] 40 | public AccountIdsObject[] AccountIds; 41 | } 42 | 43 | public class AccountIdsObject 44 | { 45 | [JsonProperty("accountId", NullValueHandling = NullValueHandling.Ignore)] 46 | public long AccountId; 47 | 48 | [JsonProperty("subType", NullValueHandling = NullValueHandling.Ignore)] 49 | public string SubType; 50 | 51 | [JsonProperty("accountStatus", NullValueHandling = NullValueHandling.Ignore)] 52 | public string AccountStatus; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/OrderWebSocketClient/SubscribeOrderWebSocketV1Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Order; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle order subscription from WebSocket 9 | /// This need authentication version 1 10 | /// 11 | public class SubscribeOrderWebSocketV1Client : WebSocketV1ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public SubscribeOrderWebSocketV1Client(string accessKey, string secretKey, string host = DEFAULT_HOST) 20 | : base(accessKey, secretKey, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Subscribe all order updates of the current account 26 | /// 27 | /// Trading symbol 28 | /// Client id 29 | public void Subscribe(string symbol, string clientId = "") 30 | { 31 | string topic = $"orders.{symbol}.update"; 32 | 33 | _WebSocket.Send($"{{ \"op\":\"sub\", \"cid\": \"{clientId}\", \"topic\":\"{topic}\" }}"); 34 | 35 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 36 | } 37 | 38 | /// 39 | /// Unsubscribe order updates 40 | /// 41 | /// Trading symbol 42 | /// Client id 43 | public void UnSubscribe(string symbol, string clientId = "") 44 | { 45 | string topic = $"orders.{symbol}.update"; 46 | 47 | _WebSocket.Send($"{{ \"op\":\"unsub\", \"cid\": \"{clientId}\", \"topic\":\"{topic}\" }}"); 48 | 49 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}, clientId={clientId}"); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/OrderWebSocketClient/SubscribeOrderWebSocketV2Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Order; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle order update from WebSocket 9 | /// This need authentication version 2 10 | /// 11 | public class SubscribeOrderWebSocketV2Client : WebSocketV2ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public SubscribeOrderWebSocketV2Client(string accessKey, string secretKey, string host = DEFAULT_HOST) 20 | :base(accessKey, secretKey, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Subscribe order update for these events: creation, trade, cancellation. 26 | /// 27 | /// Trading symbol (wildcard * is allowed) 28 | /// 29 | public void Subscribe(string symbol, string clientId = "") 30 | { 31 | string topic = $"orders#{symbol}"; 32 | 33 | _WebSocket.Send($"{{\"action\":\"sub\", \"ch\":\"{topic}\", \"cid\": \"{clientId}\" }}"); 34 | 35 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}"); 36 | } 37 | 38 | /// 39 | /// Unsubscribe order update 40 | /// 41 | /// Trading symbol (wildcard * is allowed) 42 | /// Client id 43 | public void UnSubscribe(string symbol, string clientId = "") 44 | { 45 | string topic = $"orders#{symbol}"; 46 | 47 | _WebSocket.Send($"{{\"action\":\"unsub\", \"ch\":\"{topic}\", \"cid\": \"{clientId}\" }}"); 48 | 49 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}"); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/SubscribeLast24hCandlestickResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.WebSocket; 2 | 3 | namespace Huobi.SDK.Model.Response.Market 4 | { 5 | /// 6 | /// SubscribeCandlestick response 7 | /// 8 | public class SubscribeLast24hCandlestickResponse : WebSocketResponseBase 9 | { 10 | /// 11 | /// Response body from req 12 | /// 13 | public Tick data; 14 | 15 | /// 16 | /// Response body from sub 17 | /// 18 | public Tick tick; 19 | 20 | /// 21 | /// Candlestick 22 | /// 23 | public class Tick 24 | { 25 | /// 26 | /// UNIX epoch timestamp in second as response id 27 | /// 28 | public long id; 29 | 30 | /// 31 | /// UNIX epoch timestamp in millisecond of this tick 32 | /// 33 | public long ts; 34 | 35 | /// 36 | /// Aggregated trading volume during the interval (in base currency) 37 | /// 38 | public float amount; 39 | 40 | /// 41 | /// Number of trades during the interval 42 | /// 43 | public int count; 44 | 45 | /// 46 | /// Opening price during the interval 47 | /// 48 | public float open; 49 | 50 | /// 51 | /// Closing price during the interval 52 | /// 53 | public float close; 54 | 55 | /// 56 | /// Low price during the interval 57 | /// 58 | public float low; 59 | 60 | /// 61 | /// High price during the interval 62 | /// 63 | public float high; 64 | 65 | /// 66 | /// Aggregated trading value during the interval (in quote currency) 67 | /// 68 | public float vol; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/WebSocketClientBase/GZipDecompresser.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.IO.Compression; 3 | using System.Text; 4 | 5 | namespace Huobi.SDK.Core.Client.WebSocketClientBase 6 | { 7 | /// 8 | /// Responsible to GZIP decompress 9 | /// 10 | public class GZipDecompresser 11 | { 12 | /// 13 | /// Decompress the byte array to UTF8 string 14 | /// 15 | /// byte array 16 | /// UTF8 string 17 | public static string Decompress(byte[] input) 18 | { 19 | using (var stream = new GZipStream(new MemoryStream(input), CompressionMode.Decompress)) 20 | { 21 | const int size = 4096; 22 | byte[] buffer = new byte[size]; 23 | 24 | using (var memory = new MemoryStream()) 25 | { 26 | int count = 0; 27 | do 28 | { 29 | count = stream.Read(buffer, 0, size); 30 | if (count > 0) 31 | { 32 | memory.Write(buffer, 0, count); 33 | } 34 | } while (count > 0); 35 | 36 | return Encoding.UTF8.GetString(memory.ToArray()); 37 | } 38 | } 39 | } 40 | 41 | /// 42 | /// Compress the UTF8 string to byte array. 43 | /// This method is only used in Unit Test in SDK. 44 | /// 45 | /// UTF8 string 46 | /// byte array 47 | public static byte[] Compress(string input) 48 | { 49 | byte[] raw = Encoding.UTF8.GetBytes(input); 50 | 51 | using (MemoryStream memory = new MemoryStream()) 52 | { 53 | using (GZipStream gzip = new GZipStream(memory, 54 | CompressionMode.Compress, true)) 55 | { 56 | gzip.Write(raw, 0, raw.Length); 57 | } 58 | return memory.ToArray(); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/GetLast24hCandlestickResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Market 2 | { 3 | /// 4 | /// GetLast24hCandlestick response 5 | /// 6 | public class GetLast24hCandlestickResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// The data stream 15 | /// 16 | public string ch; 17 | 18 | /// 19 | /// The timestamp (millisecond) when API respond 20 | /// 21 | public long ts; 22 | 23 | /// 24 | /// Response body 25 | /// 26 | public Candlestick tick; 27 | 28 | /// 29 | /// Candlestick detail 30 | /// 31 | public class Candlestick 32 | { 33 | /// 34 | /// Unix timestamp in seconds 35 | /// 36 | public long id; 37 | 38 | /// 39 | /// The aggregated trading volume in USDT of last 24h 40 | /// 41 | public float amount; 42 | 43 | /// 44 | /// The number of completed trades of last 24h 45 | /// 46 | public int count; 47 | 48 | /// 49 | /// The opening price of last 24h 50 | /// 51 | public float open; 52 | 53 | /// 54 | /// The closing price of last 24h 55 | /// 56 | public float close; 57 | 58 | /// 59 | /// The low price of last 24h 60 | /// 61 | public float low; 62 | 63 | /// 64 | /// The high price of last 24h 65 | /// 66 | public float high; 67 | 68 | /// 69 | /// The trading volume in base currency of last 24h 70 | /// 71 | public float vol; 72 | 73 | public long version; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/GetLast24hCandlesticksResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Market 2 | { 3 | /// 4 | /// GetLast24hCandlestick response 5 | /// 6 | public class GetAllSymbolsLast24hCandlesticksAskBidResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// The timestamp (millisecond) when API respond 15 | /// 16 | public long ts; 17 | 18 | /// 19 | /// Response body 20 | /// 21 | public Candlestick[] data; 22 | 23 | /// 24 | /// Candlestick detail 25 | /// 26 | public class Candlestick 27 | { 28 | /// 29 | /// The trading symbol 30 | /// 31 | public string symbol; 32 | 33 | /// 34 | /// The aggregated trading volume in USDT of last 24h 35 | /// 36 | public float amount; 37 | 38 | /// 39 | /// The number of completed trades of last 24h 40 | /// 41 | public int count; 42 | 43 | /// 44 | /// The opening price of last 24h 45 | /// 46 | public float open; 47 | 48 | /// 49 | /// The closing price of last 24h 50 | /// 51 | public float close; 52 | 53 | /// 54 | /// The low price of last 24h 55 | /// 56 | public float low; 57 | 58 | /// 59 | /// The high price of last 24h 60 | /// 61 | public float high; 62 | 63 | /// 64 | /// The trading volume in base currency of last 24h 65 | /// 66 | public float vol; 67 | 68 | public float bid; 69 | 70 | public float bidSize; 71 | 72 | public float ask; 73 | 74 | public float askSize; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/AccountWebSocketClient/SubscribeAccountWebSocketV2Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Account; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle account asset subscription from WebSocket 9 | /// This need authentication version 2 10 | /// 11 | public class SubscribeAccountWebSocketV2Client : WebSocketV2ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public SubscribeAccountWebSocketV2Client(string accessKey, string secretKey,string sign, string host = DEFAULT_HOST) 20 | :base(accessKey, secretKey,sign, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Subscribe all balance updates of the current account 26 | /// 27 | /// Trigger mode 28 | /// 0: Only update when account balance changed 29 | /// 1: Update when either account balance changed or available balance changed 30 | /// Client id 31 | public void Subscribe(string mode, string clientId = "") 32 | { 33 | string topic = $"accounts.update#{mode}"; 34 | 35 | _WebSocket.Send($"{{\"action\":\"sub\", \"cid\": \"{clientId}\", \"ch\":\"{topic}\"}}"); 36 | 37 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}"); 38 | } 39 | 40 | /// 41 | /// Unsubscribe balance updates 42 | /// 43 | /// Trigger mode 44 | /// Client id 45 | public void UnSubscribe(string mode, string clientId = "") 46 | { 47 | string topic = $"accounts.update#{mode}"; 48 | 49 | _WebSocket.Send($"{{\"action\":\"unsub\", \"cid\": \"{clientId}\", \"ch\":\"{topic}\" }}"); 50 | 51 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}"); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/OrderWebSocketClient/SubscribeTradeClearWebSocketV2Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Order; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle trade clear from WebSocket 9 | /// This need authentication version 2 10 | /// 11 | public class SubscribeTradeClearWebSocketV2Client : WebSocketV2ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public SubscribeTradeClearWebSocketV2Client(string accessKey, string secretKey, string host = DEFAULT_HOST) 20 | :base(accessKey, secretKey, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Subscribe trade details including transaction fee and transaction fee deduction etc. 26 | /// It only updates when transaction occurs. 27 | /// 28 | /// Trading symbol (wildcard * is allowed) 29 | /// 30 | public void Subscribe(string symbol, string clientId = "") 31 | { 32 | string topic = $"trade.clearing#{symbol}"; 33 | 34 | _WebSocket.Send($"{{\"action\":\"sub\", \"cid\": \"{clientId}\", \"ch\":\"{topic}\" }}"); 35 | 36 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 37 | } 38 | 39 | /// 40 | /// Unsubscribe trade update 41 | /// 42 | /// Trading symbol (wildcard * is allowed) 43 | /// Client id 44 | public void UnSubscribe(string symbol, string clientId = "") 45 | { 46 | string topic = $"trade.clearing#{symbol}"; 47 | 48 | _WebSocket.Send($"{{\"action\":\"unsub\", \"cid\": \"{clientId}\", \"ch\":\"{topic}\" }}"); 49 | 50 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/AccountWebSocketClient/SubscribeAccountWebSocketV1Client.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Account; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle account asset subscription from WebSocket 9 | /// This need authentication version 1 10 | /// 11 | public class SubscribeAccountWebSocketV1Client : WebSocketV1ClientBase 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// API Access Key 17 | /// API Secret Key 18 | /// API Host 19 | public SubscribeAccountWebSocketV1Client(string accessKey, string secretKey,string sign, string host = DEFAULT_HOST) 20 | :base(accessKey, secretKey,sign, host) 21 | { 22 | } 23 | 24 | /// 25 | /// Subscribe all balance updates of the current account 26 | /// 27 | /// Whether to include frozen balance. 28 | /// 1 to include frozen balance 29 | /// 0 to not 30 | /// Client id 31 | public void Subscribe(string model, string clientId = "") 32 | { 33 | string topic = "accounts"; 34 | 35 | _WebSocket.Send($"{{ \"op\":\"sub\", \"cid\": \"{clientId}\", \"topic\":\"{topic}\", \"model\": \"{model}\" }}"); 36 | 37 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, model={model}"); 38 | } 39 | 40 | /// 41 | /// Unsubscribe balance updates 42 | /// 43 | /// Whether to include frozen balance. 44 | /// Client id 45 | public void UnSubscribe(string model, string clientId = "") 46 | { 47 | string topic = "accounts"; 48 | 49 | _WebSocket.Send($"{{ \"op\":\"unsub\", \"cid\": \"{clientId}\", \"topic\":\"{topic}\", \"model\": \"{model}\" }}"); 50 | 51 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}, model={model}"); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Margin/GetCrossLoanInfoResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Huobi.SDK.Model.Response.Margin 5 | { 6 | /// 7 | /// GetCrossLoanInfo response 8 | /// 9 | public class GetCrossLoanInfoResponse 10 | { 11 | /// 12 | /// Response status 13 | /// 14 | public string status; 15 | 16 | /// 17 | /// Error code 18 | /// 19 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 20 | public string errorCode; 21 | 22 | /// 23 | /// Error message 24 | /// 25 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 26 | public string errorMessage; 27 | 28 | /// 29 | /// Response body 30 | /// 31 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 32 | public LoanInfo[] data; 33 | 34 | /// 35 | /// Loan info 36 | /// 37 | public class LoanInfo 38 | { 39 | /// 40 | /// Currency name 41 | /// 42 | public string currency; 43 | 44 | /// 45 | /// Interest rate 46 | /// 47 | [JsonProperty("interest-rate")] 48 | public string interestRate; 49 | 50 | /// 51 | /// Minimal loanable amount 52 | /// 53 | [JsonProperty("min-loan-amt")] 54 | public string minLoadAmt; 55 | 56 | /// 57 | /// Maximum loanable amount 58 | /// 59 | [JsonProperty("max-loan-amt")] 60 | public string maxLoanAmt; 61 | 62 | /// 63 | /// Remaining loanable amount 64 | /// 65 | [JsonProperty("loanable-amt")] 66 | public string loanableAmt; 67 | 68 | /// 69 | /// Actual interest trate post deduction 70 | /// 71 | [JsonProperty("actual-rate")] 72 | public string ActualRate; 73 | } 74 | 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserAccountBalanceResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.SubUser 4 | { 5 | /// 6 | /// GetSubUserAccountBalance response 7 | /// 8 | public class GetSubUserAccountBalanceResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Response body 17 | /// 18 | public Account[] data; 19 | 20 | /// 21 | /// Sub account info 22 | /// 23 | public class Account 24 | { 25 | /// 26 | /// Unique account id 27 | /// 28 | public int id; 29 | 30 | /// 31 | /// The type of this account 32 | /// Possible values: [spot, margin, otc, point, super-margin] 33 | /// 34 | public string type; 35 | 36 | /// 37 | /// Account state 38 | /// Possible values: [working, lock] 39 | /// 40 | public string state; 41 | 42 | /// 43 | /// The balance details of each currency 44 | /// 45 | public Balance[] list; 46 | 47 | public class Balance 48 | { 49 | /// 50 | /// The currency of this balance 51 | /// 52 | public string currency; 53 | 54 | /// 55 | /// The balance type 56 | /// Possible values: [trade, frozen] 57 | /// 58 | public string type; 59 | 60 | /// 61 | /// The balance in the main currency unit 62 | /// 63 | public string balance; 64 | 65 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 66 | public string debt; 67 | 68 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 69 | public string available; 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountValuationResponse.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Model.Response.Account; 2 | using Newtonsoft.Json; 3 | 4 | namespace Huobi.SDK.Model.Response.Account 5 | { 6 | public class GetAccountValuationResponse 7 | { 8 | [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] 9 | public int Code; 10 | 11 | [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] 12 | public AccountValuation Data; 13 | 14 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 15 | public bool Success; 16 | 17 | public class AccountValuation 18 | { 19 | [JsonProperty("totalBalance", NullValueHandling = NullValueHandling.Ignore)] 20 | public string TotalBalance; 21 | 22 | [JsonProperty("todayProfit", NullValueHandling = NullValueHandling.Ignore)] 23 | public string TodayProfit; 24 | 25 | [JsonProperty("todayProfitRate", NullValueHandling = NullValueHandling.Ignore)] 26 | public string TodayProfitRate; 27 | 28 | [JsonProperty("", NullValueHandling = NullValueHandling.Ignore)] 29 | public ProfitAccountBalanceObject[] ProfitAccountBalanceList; 30 | 31 | [JsonProperty("", NullValueHandling = NullValueHandling.Ignore)] 32 | public UpdatedObject[] Updated; 33 | } 34 | 35 | public class ProfitAccountBalanceObject 36 | { 37 | [JsonProperty("distributionType", NullValueHandling = NullValueHandling.Ignore)] 38 | public string DistributionType; 39 | 40 | [JsonProperty("balance", NullValueHandling = NullValueHandling.Ignore)] 41 | public float Balance; 42 | 43 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 44 | public bool Success; 45 | 46 | [JsonProperty("accountBalance", NullValueHandling = NullValueHandling.Ignore)] 47 | public string AccountBalance; 48 | } 49 | 50 | public class UpdatedObject 51 | { 52 | [JsonProperty("success", NullValueHandling = NullValueHandling.Ignore)] 53 | public bool Success; 54 | 55 | [JsonProperty("time", NullValueHandling = NullValueHandling.Ignore)] 56 | public long Time; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/GetLastTradeResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// GetDepth response 7 | /// 8 | public class GetLastTradeResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// The data stream 17 | /// 18 | public string ch; 19 | 20 | /// 21 | /// The timestamp (millisecond) when API respond 22 | /// 23 | public long ts; 24 | 25 | /// 26 | /// The response body 27 | /// 28 | public Tick tick; 29 | 30 | /// 31 | /// The tick data 32 | /// 33 | public class Tick 34 | { 35 | public long id; 36 | 37 | /// 38 | /// The UNIX timestamp in milliseconds adjusted to Singapore time 39 | /// 40 | public long ts; 41 | 42 | /// 43 | /// The trade data 44 | /// 45 | public Trade[] data; 46 | 47 | /// 48 | /// The trade data 49 | /// 50 | public class Trade 51 | { 52 | /// 53 | /// The unique trade id (NEW) 54 | /// 55 | [JsonProperty(PropertyName = "trade-id")] 56 | public long tradeId; 57 | 58 | /// 59 | /// The trading volume in base currency 60 | /// 61 | public float amount; 62 | 63 | /// 64 | /// The trading price in quote currency 65 | /// 66 | public float price; 67 | 68 | /// 69 | /// The UNIX timestamp in milliseconds adjusted to Singapore time 70 | /// 71 | public long ts; 72 | 73 | /// 74 | /// The direction of the taker trade. 75 | /// Possible values: [buy, sell] 76 | /// 77 | public string direction; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/GetLastTradesResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// GetDepth response 7 | /// 8 | public class GetLastTradesResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// The data stream 17 | /// 18 | public string ch; 19 | 20 | /// 21 | /// The timestamp (millisecond) when API respond 22 | /// 23 | public long ts; 24 | 25 | /// 26 | /// The response body 27 | /// 28 | public Tick[] data; 29 | 30 | /// 31 | /// The tick data 32 | /// 33 | public class Tick 34 | { 35 | public long id; 36 | 37 | /// 38 | /// The UNIX timestamp in milliseconds adjusted to Singapore time 39 | /// 40 | public long ts; 41 | 42 | /// 43 | /// The trade data 44 | /// 45 | public Trade[] data; 46 | 47 | /// 48 | /// The trade data 49 | /// 50 | public class Trade 51 | { 52 | /// 53 | /// The unique trade id (NEW) 54 | /// 55 | [JsonProperty(PropertyName = "trade-id")] 56 | public long tradeId; 57 | 58 | /// 59 | /// The trading volume in base currency 60 | /// 61 | public float amount; 62 | 63 | /// 64 | /// The trading price in quote currency 65 | /// 66 | public float price; 67 | 68 | /// 69 | /// The UNIX timestamp in milliseconds adjusted to Singapore time 70 | /// 71 | public long ts; 72 | 73 | /// 74 | /// The direction of the taker trade. 75 | /// Possible values: [buy, sell] 76 | /// 77 | public string direction; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/SubUser/GetSubUserDepositHistoryResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Huobi.SDK.Model.Response.Wallet 3 | { 4 | public class GetSubUserDepositHistoryResponse 5 | { 6 | /// 7 | /// Status code 8 | /// 9 | public int code; 10 | 11 | /// 12 | /// Error message (if any) 13 | /// 14 | public string message; 15 | 16 | /// 17 | /// Response body 18 | /// 19 | public DepositHistory[] data; 20 | 21 | /// 22 | /// First record in next page (only valid if exceeded page size) 23 | /// 24 | public long nextId; 25 | 26 | public class DepositHistory 27 | { 28 | /// 29 | /// Deposit id 30 | /// 31 | public long id; 32 | 33 | /// 34 | /// Cryptocurrency 35 | /// 36 | public string currency; 37 | 38 | /// 39 | /// The on-chain transaction hash 40 | /// 41 | public string txHash; 42 | 43 | /// 44 | /// Block chain name 45 | /// 46 | public string chain; 47 | 48 | /// 49 | /// The number of crypto asset transferred 50 | /// 51 | public decimal amount; 52 | 53 | /// 54 | /// The deposit source address 55 | /// 56 | public string address; 57 | 58 | /// 59 | /// The deposit source address tag 60 | /// 61 | public string addressTag; 62 | 63 | /// 64 | /// The state of this transfer 65 | /// Possible values: unknown, confirming, confirmed, safe, orphan 66 | /// 67 | public string state; 68 | 69 | /// 70 | /// The timestamp in milliseconds for the transfer creation 71 | /// 72 | public long createTime; 73 | 74 | /// 75 | /// The timestamp in milliseconds for the transfer's latest update 76 | /// 77 | public long updateTime; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Wallet/GetWithdrawQuotaResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Wallet 2 | { 3 | public class GetWithdrawQuotaResponse 4 | { 5 | /// 6 | /// Status code 7 | /// 8 | public int code; 9 | 10 | /// 11 | /// Response body 12 | /// 13 | public Quota data; 14 | 15 | /// 16 | /// Quota 17 | /// 18 | public class Quota 19 | { 20 | /// 21 | /// Crypto currency 22 | /// 23 | public string currency; 24 | 25 | /// 26 | /// Chains 27 | /// 28 | public Chain[] chains; 29 | 30 | /// 31 | /// Chain info 32 | /// 33 | public class Chain 34 | { 35 | /// 36 | /// Blockchain name 37 | /// 38 | public string chain; 39 | 40 | /// 41 | /// Maximum withdraw amount in each request 42 | /// 43 | public string maxWithdrawAmt; 44 | 45 | /// 46 | /// Maximum withdraw amount in a day 47 | /// 48 | public string withdrawQuotaPerDay; 49 | 50 | /// 51 | /// Remaining withdraw quota in the day 52 | /// 53 | public string remainWithdrawQuotaPerDay; 54 | 55 | /// 56 | /// Maximum withdraw amount in a year 57 | /// 58 | public string withdrawQuotaPerYear; 59 | 60 | /// 61 | /// Remaining withdraw quota in the year 62 | /// 63 | public string remainWithdrawQuotaPerYear; 64 | 65 | /// 66 | /// Maximum withdraw amount in total 67 | /// 68 | public string withdrawQuotaTotal; 69 | 70 | /// 71 | /// Remaining withdraw quota in total 72 | /// 73 | public string remainWithdrawQuotaTotal; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/MarketWebSocketClient/TradeWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Market; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle Trade data from WebSocket 9 | /// 10 | public class TradeWebSocketClient : WebSocketClientBase 11 | { 12 | 13 | /// 14 | /// Constructor 15 | /// 16 | /// websockethost 17 | public TradeWebSocketClient(string host = DEFAULT_HOST) 18 | :base(host) 19 | { 20 | } 21 | 22 | /// 23 | /// Request latest 300 trade data 24 | /// 25 | /// Trading symbol 26 | /// Client id 27 | public void Req(string symbol, string clientId = "") 28 | { 29 | string topic = $"market.{symbol}.trade.detail"; 30 | 31 | _WebSocket.Send($"{{\"req\": \"{topic}\",\"id\": \"{clientId}\" }}"); 32 | 33 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}, clientId={clientId}"); 34 | } 35 | 36 | 37 | /// 38 | /// Subscribe latest completed trade in tick by tick mode 39 | /// 40 | /// Trading symbol 41 | /// Client id 42 | public void Subscribe(string symbol, string clientId = "") 43 | { 44 | string topic = $"market.{symbol}.trade.detail"; 45 | 46 | _WebSocket.Send($"{{ \"sub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 47 | 48 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 49 | } 50 | 51 | /// 52 | /// Unsubscribe trade 53 | /// 54 | /// Trading symbol 55 | /// Client id 56 | public void UnSubscribe(string symbol, string clientId = "") 57 | { 58 | string topic = $"market.{symbol}.trade.detail"; 59 | 60 | _WebSocket.Send($"{{ \"unsub\": \"market.{symbol}.trade.detail\",\"id\": \"{clientId}\" }}"); 61 | 62 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}, clientId={clientId}"); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountLedgerResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | /// 6 | /// GetAccountHistory response 7 | /// 8 | public class GetAccountLedgerResponse 9 | { 10 | /// 11 | /// Status code 12 | /// 13 | public int code; 14 | 15 | /// 16 | /// Error message (if any) 17 | /// 18 | public string message; 19 | 20 | /// 21 | /// Response body 22 | /// 23 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 24 | public Ledger[] data; 25 | 26 | /// 27 | /// First record ID in next page (only valid if exceeded page size) 28 | /// 29 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 30 | public long nextId; 31 | 32 | /// 33 | /// Ledger 34 | /// 35 | public class Ledger 36 | { 37 | /// 38 | /// Account Id 39 | /// 40 | public long accountId; 41 | 42 | /// 43 | /// Cryptocurrency 44 | /// 45 | public string currency; 46 | 47 | /// 48 | /// Transaction amount (income positive, expenditure negative) 49 | /// 50 | public string transactAmt; 51 | 52 | /// 53 | /// Transaction type 54 | /// Possible values: [transfer] 55 | /// 56 | public string transactType; 57 | 58 | /// 59 | /// Transfer type 60 | /// 61 | public string transferType; 62 | 63 | /// 64 | /// Transaction ID 65 | /// 66 | public long transactId; 67 | 68 | /// 69 | /// Transaction time 70 | /// 71 | public long transactTime; 72 | 73 | /// 74 | /// Transferer’s account ID 75 | /// 76 | public long transferer; 77 | 78 | /// 79 | /// Transferee’s account ID 80 | /// 81 | public long transferee; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Huobi.SDK.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Huobi.SDK.Core", "Huobi.SDK.Core\Huobi.SDK.Core.csproj", "{81118376-9EF7-49E6-94DC-5B0CF91499DE}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Huobi.SDK.Core.Test", "Huobi.SDK.Core.Test\Huobi.SDK.Core.Test.csproj", "{0ECB2FAB-04BE-4040-B868-B0FA0B068DA6}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Huobi.SDK.Model", "Huobi.SDK.Model\Huobi.SDK.Model.csproj", "{F78D398D-C926-45C7-B338-1F5CFEF3B396}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Huobi.SDK.Example", "Huobi.SDK.Example\Huobi.SDK.Example.csproj", "{AAD2DD07-E5CF-4518-81F3-675D14658639}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {81118376-9EF7-49E6-94DC-5B0CF91499DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {81118376-9EF7-49E6-94DC-5B0CF91499DE}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {81118376-9EF7-49E6-94DC-5B0CF91499DE}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {81118376-9EF7-49E6-94DC-5B0CF91499DE}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {0ECB2FAB-04BE-4040-B868-B0FA0B068DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {0ECB2FAB-04BE-4040-B868-B0FA0B068DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {0ECB2FAB-04BE-4040-B868-B0FA0B068DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {0ECB2FAB-04BE-4040-B868-B0FA0B068DA6}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {F78D398D-C926-45C7-B338-1F5CFEF3B396}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {F78D398D-C926-45C7-B338-1F5CFEF3B396}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {F78D398D-C926-45C7-B338-1F5CFEF3B396}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {F78D398D-C926-45C7-B338-1F5CFEF3B396}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {AAD2DD07-E5CF-4518-81F3-675D14658639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {AAD2DD07-E5CF-4518-81F3-675D14658639}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {AAD2DD07-E5CF-4518-81F3-675D14658639}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {AAD2DD07-E5CF-4518-81F3-675D14658639}.Release|Any CPU.Build.0 = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(MonoDevelopProperties) = preSolution 36 | version = 2.2.0 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Order/CancelOrdersByIdsResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Order 4 | { 5 | /// 6 | /// CancelOrdersByIds response 7 | /// 8 | public class CancelOrdersByIdsResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Error code 17 | /// 18 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 19 | public string errorCode; 20 | 21 | /// 22 | /// Error message 23 | /// 24 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorMessage; 26 | 27 | /// 28 | /// Response body 29 | /// 30 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 31 | public Body data; 32 | 33 | /// 34 | /// Response body 35 | /// 36 | public class Body 37 | { 38 | /// 39 | /// Cancelled order list 40 | /// 41 | public string[] success; 42 | 43 | /// 44 | /// Failed order list 45 | /// 46 | public FailedOrder[] failed; 47 | 48 | public class FailedOrder 49 | { 50 | /// 51 | /// Order id 52 | /// 53 | [JsonProperty("order-id", NullValueHandling = NullValueHandling.Ignore)] 54 | public string orderId; 55 | 56 | /// 57 | /// Client order id 58 | /// 59 | [JsonProperty("client-order-id", NullValueHandling = NullValueHandling.Ignore)] 60 | public string clientOrderId; 61 | 62 | /// 63 | /// Error code 64 | /// 65 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 66 | public string errorCode; 67 | 68 | /// 69 | /// Error message 70 | /// 71 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 72 | public string errorMessage; 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/MarketWebSocketClient/Last24hCandlestickWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Market; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle last 24h candlestick data from WebSocket 9 | /// 10 | public class Last24hCandlestickWebSocketClient : WebSocketClientBase 11 | { 12 | 13 | /// 14 | /// Constructor 15 | /// 16 | /// websockethost 17 | public Last24hCandlestickWebSocketClient(string host = DEFAULT_HOST) 18 | :base(host) 19 | { 20 | } 21 | 22 | /// 23 | /// Request full candlestick data 24 | /// 25 | /// Trading symbol 26 | /// Client id 27 | public void Req(string symbol, string clientId = "") 28 | { 29 | string topic = $"market.{symbol}.detail"; 30 | 31 | _WebSocket.Send($"{{\"req\": \"{topic}\",\"id\": \"{clientId}\" }}"); 32 | 33 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}, clientId={clientId}"); 34 | } 35 | 36 | 37 | /// 38 | /// Subscribe latest 24h market stats 39 | /// 40 | /// Trading symbol 41 | /// Client id 42 | public void Subscribe(string symbol, string clientId = "") 43 | { 44 | string topic = $"market.{symbol}.detail"; 45 | 46 | _WebSocket.Send($"{{\"sub\": \"market.{symbol}.detail\",\"id\": \"{clientId}\" }}"); 47 | 48 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 49 | } 50 | 51 | /// 52 | /// Unsubscribe latest 24 market stats 53 | /// 54 | /// Trading symbol 55 | /// Client id 56 | public void UnSubscribe(string symbol, string clientId = "") 57 | { 58 | string topic = $"market.{symbol}.detail"; 59 | 60 | _WebSocket.Send($"{{\"unsub\": \"market.{symbol}.detail\",\"id\": \"{clientId}\" }}"); 61 | 62 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}, clientId={clientId}"); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/GetRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Huobi.SDK.Core 7 | { 8 | /// 9 | /// Manage the HTTP GET request parameters 10 | /// 11 | public class GetRequest 12 | { 13 | private Dictionary _params; 14 | 15 | /// 16 | /// Constructor 17 | /// 18 | /// The initial object 19 | public GetRequest(GetRequest request = null) 20 | { 21 | if (request != null) 22 | { 23 | _params = new Dictionary(request._params); 24 | } 25 | else 26 | { 27 | _params = new Dictionary(); 28 | } 29 | } 30 | 31 | /// 32 | /// Add URL escape property and value pair 33 | /// 34 | /// property 35 | /// value 36 | /// Current object 37 | public GetRequest AddParam(string property, string value) 38 | { 39 | if ((property != null) && (value != null)) 40 | { 41 | _params.Add(Uri.EscapeDataString(property), Uri.EscapeDataString(value)); 42 | } 43 | 44 | return this; 45 | } 46 | 47 | /// 48 | /// Add and merge another object 49 | /// 50 | /// The object that want to add 51 | /// Current object 52 | public GetRequest AddParam(GetRequest request) 53 | { 54 | _params.Concat(request._params); 55 | 56 | return this; 57 | } 58 | 59 | /// 60 | /// Concat the property and value pair 61 | /// 62 | /// string 63 | public string BuildParams() 64 | { 65 | if (_params.Count == 0) 66 | { 67 | return string.Empty; 68 | } 69 | 70 | StringBuilder sb = new StringBuilder(); 71 | 72 | foreach (var para in _params.OrderBy(i => i.Key, StringComparer.Ordinal)) 73 | { 74 | sb.Append('&'); 75 | sb.Append(para.Key).Append('=').Append(para.Value); 76 | } 77 | 78 | return sb.ToString().Substring(1); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Market/GetLast24hCandlestickAskBidResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Huobi.SDK.Model.Response.Market 2 | { 3 | /// 4 | /// GetCandlestick response 5 | /// 6 | public class GetLast24hCandlestickAskBidResponse 7 | { 8 | /// 9 | /// Response status 10 | /// 11 | public string status; 12 | 13 | /// 14 | /// The data stream 15 | /// 16 | public string ch; 17 | 18 | /// 19 | /// The timestamp (millisecond) when API respond 20 | /// 21 | public long ts; 22 | 23 | /// 24 | /// The response body 25 | /// 26 | public Tick tick; 27 | 28 | /// 29 | /// The tick data 30 | /// 31 | public class Tick 32 | { 33 | /// 34 | /// Unix timestamp in seconds 35 | /// 36 | public long id; 37 | 38 | /// 39 | /// The aggregated trading volume in USDT 40 | /// 41 | public float amount; 42 | 43 | /// 44 | /// The number of completed trades 45 | /// 46 | public int count; 47 | 48 | /// 49 | /// The opening price 50 | /// 51 | public float open; 52 | 53 | /// 54 | /// The closing price 55 | /// 56 | public float close; 57 | 58 | /// 59 | /// The low price 60 | /// 61 | public float low; 62 | 63 | /// 64 | /// The high price 65 | /// 66 | public float high; 67 | 68 | /// 69 | /// The trading volume in base currency 70 | /// 71 | public float vol; 72 | 73 | /// 74 | /// The internal data 75 | /// 76 | public long version; 77 | 78 | /// 79 | /// The current best ask in format [price, quote volume] 80 | /// 81 | public float[] ask; 82 | 83 | /// 84 | /// The current best bit in format [price, quote volume] 85 | /// 86 | public float[] bid; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Huobi.SDK.Example/StableCoinClientExample.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client; 2 | using Huobi.SDK.Core.Log; 3 | 4 | namespace Huobi.SDK.Example 5 | { 6 | public class StableCoinClientExample 7 | { 8 | private static PerformanceLogger _logger = PerformanceLogger.GetInstance(); 9 | 10 | public static void RunAll() 11 | { 12 | GetStableCoin(); 13 | 14 | ExchangeStableCoin(); 15 | } 16 | 17 | private static void GetStableCoin() 18 | { 19 | var stableCoinClient = new StableCointClient(Config.AccessKey, Config.SecretKey,Config.Sign); 20 | 21 | _logger.Start(); 22 | var result = stableCoinClient.GetStableCoinAsync("tusd", "1000", "sell").Result; 23 | _logger.StopAndLog(); 24 | 25 | if (result != null) 26 | { 27 | switch (result.status) 28 | { 29 | case "ok": 30 | { 31 | var d = result.data; 32 | AppLogger.Info($"Get stable coin successfully, quoteId: {d.quoteId}, currency: {d.currency}, amount: {d.amount}, fee: {d.exchangeFee}"); 33 | break; 34 | } 35 | case "error": 36 | { 37 | AppLogger.Info($"Get stable coin fail, error code: {result.errorCode}, error message: {result.errorMessage}"); 38 | break; 39 | } 40 | } 41 | } 42 | } 43 | 44 | private static void ExchangeStableCoin() 45 | { 46 | var stableCoinClient = new StableCointClient(Config.AccessKey, Config.SecretKey,Config.Sign); 47 | 48 | _logger.Start(); 49 | var response = stableCoinClient.ExchangeStableCoinAsync("123").Result; 50 | _logger.StopAndLog(); 51 | 52 | if (response != null) 53 | { 54 | switch (response.status) 55 | { 56 | case "ok": 57 | { 58 | AppLogger.Info($"Exchange successfully"); 59 | break; 60 | } 61 | case "error": 62 | { 63 | AppLogger.Info($"Exchange fail, error code: {response.errorCode}, error message: {response.errorMessage}"); 64 | break; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/StableCoinClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Huobi.SDK.Core.RequestBuilder; 3 | using Huobi.SDK.Model.Response.StableCoin; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to operate stable coin 9 | /// 10 | public class StableCointClient 11 | { 12 | private const string GET_METHOD = "GET"; 13 | private const string POST_METHOD = "POST"; 14 | 15 | private const string DEFAULT_HOST = "api.huobi.pro"; 16 | 17 | private readonly PrivateUrlBuilder _urlBuilder; 18 | 19 | /// 20 | /// Constructor 21 | /// 22 | /// Access Key 23 | /// Secret Key 24 | /// the host that the client connects to 25 | public StableCointClient(string accessKey, string secretKey,string sign, string host = DEFAULT_HOST) 26 | { 27 | _urlBuilder = new PrivateUrlBuilder(accessKey, secretKey, host,sign); 28 | } 29 | 30 | /// 31 | /// Get stable coin quote 32 | /// 33 | /// Stable coin name (USDT/PAX/USDC/TUSD) 34 | /// Amount of stable coin to exchange (the value must be an intger) 35 | /// Type of the exchange (buy/sell) 36 | /// GetStableCoinResponse 37 | public async Task GetStableCoinAsync(string currency, string amount, string type) 38 | { 39 | var request = new GetRequest() 40 | .AddParam("currency", currency) 41 | .AddParam("amount", amount) 42 | .AddParam("type", type); 43 | string url = _urlBuilder.Build(GET_METHOD, "/v1/stable-coin/quote", request); 44 | 45 | return await HttpRequest.GetAsync(url); 46 | } 47 | 48 | /// 49 | /// Exchange stable coin 50 | /// 51 | /// Stable currency quoteID 52 | /// ExchangeStableCoinResponse 53 | public async Task ExchangeStableCoinAsync(string quoteId) 54 | { 55 | string url = _urlBuilder.Build(POST_METHOD, $"/v1/stable-coin/exchange"); 56 | 57 | string body = $"{{ \"quote-id\":\"{quoteId}\" }}"; 58 | 59 | return await HttpRequest.PostAsync(url, body); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Account/GetAccountBalanceResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Account 4 | { 5 | /// 6 | /// GetAccountBalance response 7 | /// 8 | public class GetAccountBalanceResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Error code 17 | /// 18 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 19 | public string errorCode; 20 | 21 | /// 22 | /// Error message 23 | /// 24 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorMessage; 26 | 27 | /// 28 | /// Response body 29 | /// 30 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 31 | public Data data; 32 | 33 | /// 34 | /// Account info 35 | /// 36 | public class Data 37 | { 38 | /// 39 | /// Unique account id 40 | /// 41 | public int id; 42 | 43 | /// 44 | /// The type of this account 45 | /// Possible values: [spot, margin, otc, point, super-margin] 46 | /// 47 | public string type; 48 | 49 | /// 50 | /// Account state 51 | /// Possible values: [working, lock] 52 | /// 53 | public string state; 54 | 55 | /// 56 | /// The balance details of each currency 57 | /// 58 | public Balance[] list; 59 | 60 | public class Balance 61 | { 62 | /// 63 | /// The currency of this balance 64 | /// 65 | public string currency; 66 | 67 | /// 68 | /// The balance type 69 | /// Possible values: [trade, frozen] 70 | /// 71 | public string type; 72 | 73 | /// 74 | /// The balance in the main currency unit 75 | /// 76 | public string balance; 77 | 78 | public string debt; 79 | 80 | public string available; 81 | 82 | [JsonProperty("seq-num", NullValueHandling = NullValueHandling.Ignore)] 83 | public string seqNum; 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/MarketWebSocketClient/DepthWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Market; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle Depth data from WebSocket 9 | /// 10 | public class DepthWebSocketClient : WebSocketClientBase 11 | { 12 | 13 | /// 14 | /// Constructor 15 | /// 16 | /// websockethost 17 | public DepthWebSocketClient(string host = DEFAULT_HOST) 18 | :base(host) 19 | { 20 | } 21 | 22 | /// 23 | /// Request full depth data 24 | /// 25 | /// Trading symbol 26 | /// Market depth aggregation level 27 | /// Possible values: step0, step1, step2, step3, step4, step5 28 | /// Client id 29 | public void Req(string symbol, string type, string clientId = "") 30 | { 31 | string topic = $"market.{symbol}.depth.{type}"; 32 | 33 | _WebSocket.Send($"{{\"req\": \"{topic}\",\"id\": \"{clientId}\" }}"); 34 | 35 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}, clientId={clientId}"); 36 | } 37 | 38 | 39 | /// 40 | /// Subscribe latest market by price order book in snapshot mode at 1-second interval. 41 | /// 42 | /// Trading symbol 43 | /// Market depth aggregation level 44 | /// Client id 45 | public void Subscribe(string symbol, string type, string clientId = "") 46 | { 47 | string topic = $"market.{symbol}.depth.{type}"; 48 | 49 | _WebSocket.Send($"{{\"sub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 50 | 51 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 52 | } 53 | 54 | /// 55 | /// Unsubscribe market by price order book 56 | /// 57 | /// Trading symbol 58 | /// Market depth aggregation level 59 | /// Client id 60 | public void UnSubscribe(string symbol, string type, string clientId = "") 61 | { 62 | string topic = $"market.{symbol}.depth.{type}"; 63 | 64 | _WebSocket.Send($"{{\"unsub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 65 | 66 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Margin/GetIsolatedLoanInfoResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Margin 4 | { 5 | /// 6 | /// GetIsolatedLoanInfo response 7 | /// 8 | public class GetIsolatedLoanInfoResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Error code 17 | /// 18 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 19 | public string errorCode; 20 | 21 | /// 22 | /// Error message 23 | /// 24 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorMessage; 26 | 27 | /// 28 | /// Response body 29 | /// 30 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 31 | public LoanInfo[] data; 32 | 33 | /// 34 | /// Loan info 35 | /// 36 | public class LoanInfo 37 | { 38 | /// 39 | /// Trading symbol 40 | /// 41 | public string symbol; 42 | 43 | /// 44 | /// Currency list 45 | /// 46 | public Currency[] currencies; 47 | 48 | /// 49 | /// Currency detail 50 | /// 51 | public class Currency 52 | { 53 | /// 54 | /// Currency name 55 | /// 56 | public string currency; 57 | 58 | /// 59 | /// Interest rate 60 | /// 61 | [JsonProperty("interest-rate")] 62 | public string interestRate; 63 | 64 | /// 65 | /// Minimal loanable amount 66 | /// 67 | [JsonProperty("min-loan-amt")] 68 | public string minLoadAmt; 69 | 70 | /// 71 | /// Maximum loanable amount 72 | /// 73 | [JsonProperty("max-loan-amt")] 74 | public string maxLoanAmt; 75 | 76 | /// 77 | /// Remaining loanable amount 78 | /// 79 | [JsonProperty("loanable-amt")] 80 | public string loanableAmt; 81 | 82 | /// 83 | /// Actual interest rate 84 | /// 85 | [JsonProperty("actual-rate")] 86 | public string ActualRate; 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/RequestBuilder/WebSocketV1RequestBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.Model; 3 | 4 | namespace Huobi.SDK.Core.RequestBuilder 5 | { 6 | public class WebSocketV1RequestBuilder 7 | { 8 | private readonly string _host; 9 | private readonly string _path; 10 | private const string _sMVaue2 = "ED25519"; 11 | private readonly string _sign; 12 | private const string _aKKey = "AccessKeyId"; 13 | private readonly string _aKValue; 14 | private const string _sMKey = "SignatureMethod"; 15 | private const string _sMVaue = "HmacSHA256"; 16 | private const string _sVKey = "SignatureVersion"; 17 | private const string _sVValue = "2"; 18 | private const string _tKey = "Timestamp"; 19 | 20 | private readonly Signer _signer; 21 | private readonly Ed25519Signer _signer255; 22 | public WebSocketV1RequestBuilder(string accessKey, string secretKey, string host, string path,string sign) 23 | {_sign=sign; 24 | _aKValue = accessKey; 25 | if(sign=="256"){ 26 | _signer = new Signer(secretKey); 27 | _signer255=null; 28 | 29 | }else{ 30 | _signer=null; 31 | _signer255 = new Ed25519Signer(secretKey); 32 | 33 | } 34 | _host = host; 35 | _path = path; 36 | } 37 | 38 | public string Build() 39 | { 40 | return Build(DateTime.UtcNow); 41 | } 42 | 43 | public string Build(DateTime utcDateTime) 44 | { 45 | string strDateTime = utcDateTime.ToString("s"); 46 | 47 | var request = new GetRequest() 48 | .AddParam(_aKKey, _aKValue) 49 | 50 | .AddParam(_sVKey, _sVValue) 51 | .AddParam(_tKey, strDateTime); 52 | 53 | // string signature = _signer.Sign("GET", _host, _path, request.BuildParams()); 54 | if(_sign=="256"){ 55 | request .AddParam(_sMKey, _sMVaue);; 56 | 57 | }else{ 58 | request .AddParam(_sMKey, _sMVaue2); 59 | 60 | } 61 | // string signature = _signer.Sign("GET", _host, _path, request.BuildParams()); 62 | 63 | string signature; 64 | if(_sign=="256"){ 65 | signature= _signer.Sign("GET", _host, _path, request.BuildParams()); 66 | }else{ 67 | // signature = _signer255.Sign("GET", _host, _path, request.BuildParams()); 68 | signature = _signer255.Sign("GET" + "\n" + _host + "\n" + _path + "\n" + request.BuildParams()); 69 | } 70 | 71 | var auth = new WebSocketAuthenticationRequest 72 | { 73 | AccessKeyId = _aKValue, 74 | Timestamp = strDateTime, 75 | Signature = signature 76 | }; 77 | 78 | return auth.ToJson(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/RequestBuilder/WebSocketV2RequestBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Huobi.SDK.Core.Model; 3 | 4 | namespace Huobi.SDK.Core.RequestBuilder 5 | { 6 | public class WebSocketV2RequestBuilder 7 | { 8 | private readonly string _host; 9 | private readonly string _path; 10 | private const string _sMVaue2 = "ED25519"; 11 | private const string _aKKey = "accessKey"; 12 | private readonly string _aKValue; 13 | private const string _sMKey = "signatureMethod"; 14 | private const string _sMVaue = "HmacSHA256"; 15 | private const string _sVKey = "signatureVersion"; 16 | private const string _sVValue = "2.1"; 17 | private const string _tKey = "timestamp"; 18 | private readonly string _sign; 19 | private Signer _signer; 20 | private readonly Ed25519Signer _signer255; 21 | public WebSocketV2RequestBuilder(string accessKey, string secretKey, string host, string path,string sign) 22 | { 23 | _sign=sign; 24 | _aKValue = accessKey; 25 | if(sign=="256"){ 26 | _signer = new Signer(secretKey); 27 | _signer255=null; 28 | 29 | }else{ 30 | _signer=null; 31 | _signer255 = new Ed25519Signer(secretKey); 32 | 33 | } 34 | 35 | 36 | _host = host; 37 | _path = path; 38 | } 39 | 40 | public string Build() 41 | { 42 | return Build(DateTime.UtcNow); 43 | } 44 | 45 | public string Build(DateTime utcDateTime) 46 | { 47 | string strDateTime = utcDateTime.ToString("s"); 48 | 49 | var request = new GetRequest() 50 | .AddParam(_aKKey, _aKValue) 51 | 52 | .AddParam(_sVKey, _sVValue) 53 | .AddParam(_tKey, strDateTime); 54 | 55 | if(_sign=="256"){ 56 | request .AddParam(_sMKey, _sMVaue);; 57 | 58 | }else{ 59 | request .AddParam(_sMKey, _sMVaue2); 60 | 61 | } 62 | // string signature = _signer.Sign("GET", _host, _path, request.BuildParams()); 63 | 64 | string signature; 65 | if(_sign=="256"){ 66 | signature= _signer.Sign("GET", _host, _path, request.BuildParams()); 67 | }else{ 68 | // signature = _signer255.Sign("GET", _host, _path, request.BuildParams()); 69 | signature = _signer255.Sign("GET" + "\n" + _host + "\n" + _path + "\n" + request.BuildParams()); 70 | } 71 | var auth = new WebSocketAuthenticationRequestV2 72 | { 73 | @params = new WebSocketAuthenticationRequestV2.Params 74 | { 75 | accessKey = _aKValue, 76 | timestamp = strDateTime, 77 | signature = signature 78 | } 79 | }; 80 | 81 | return auth.ToJson(); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/Client/MarketWebSocketClient/CandlestickWebSocketClient.cs: -------------------------------------------------------------------------------- 1 | using Huobi.SDK.Core.Client.WebSocketClientBase; 2 | using Huobi.SDK.Core.Log; 3 | using Huobi.SDK.Model.Response.Market; 4 | 5 | namespace Huobi.SDK.Core.Client 6 | { 7 | /// 8 | /// Responsible to handle candlestick data from WebSocket 9 | /// 10 | public class CandlestickWebSocketClient : WebSocketClientBase 11 | { 12 | /// 13 | /// Constructor 14 | /// 15 | /// websockethost 16 | public CandlestickWebSocketClient(string host = DEFAULT_HOST) 17 | :base(host) 18 | { 19 | } 20 | 21 | /// 22 | /// Request the full candlestick data according to specified criteria 23 | /// 24 | /// Trading symbol 25 | /// Candlestick internval 26 | /// possible values: 1min, 5min, 15min, 30min, 60min, 4hour, 1day, 1mon, 1week, 1year 27 | /// From timestamp in second 28 | /// To timestamp in second 29 | /// Client id 30 | public void Req(string symbol, string period, int from, int to, string clientId = "") 31 | { 32 | string topic = $"market.{symbol}.kline.{period}"; 33 | 34 | _WebSocket.Send($"{{ \"req\": \"{topic}\",\"id\": \"{clientId}\", \"from\":{from}, \"to\":{to} }}"); 35 | 36 | _logger.Log(LogLevel.Info, $"WebSocket requested, topic={topic}, clientId={clientId}"); 37 | } 38 | 39 | /// 40 | /// Subscribe candlestick data 41 | /// 42 | /// Trading symbol 43 | /// Candlestick internval 44 | /// Client id 45 | public void Subscribe(string symbol, string period, string clientId = "") 46 | { 47 | string topic = $"market.{symbol}.kline.{period}"; 48 | 49 | _WebSocket.Send($"{{ \"sub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 50 | 51 | _logger.Log(LogLevel.Info, $"WebSocket subscribed, topic={topic}, clientId={clientId}"); 52 | } 53 | 54 | /// 55 | /// Unsubscribe candlestick data 56 | /// 57 | /// Trading symbol 58 | /// Candlestick interval 59 | /// Client id 60 | public void UnSubscribe(string symbol, string period, string clientId = "") 61 | { 62 | string topic = $"market.{symbol}.kline.{period}"; 63 | 64 | _WebSocket.Send($"{{ \"unsub\": \"{topic}\",\"id\": \"{clientId}\" }}"); 65 | 66 | _logger.Log(LogLevel.Info, $"WebSocket unsubscribed, topic={topic}, clientId={clientId}"); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Huobi.SDK.Model/Response/Margin/GetIsolatedMarginAccountResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Huobi.SDK.Model.Response.Margin 4 | { 5 | /// 6 | /// GetIsolatedMarginAccount response 7 | /// 8 | public class GetIsolatedMarginAccountResponse 9 | { 10 | /// 11 | /// Response status 12 | /// 13 | public string status; 14 | 15 | /// 16 | /// Error code 17 | /// 18 | [JsonProperty("err-code", NullValueHandling = NullValueHandling.Ignore)] 19 | public string errorCode; 20 | 21 | /// 22 | /// Error message 23 | /// 24 | [JsonProperty("err-msg", NullValueHandling = NullValueHandling.Ignore)] 25 | public string errorMessage; 26 | 27 | /// 28 | /// Response body 29 | /// 30 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 31 | public Account[] data; 32 | 33 | /// 34 | /// Loan info 35 | /// 36 | public class Account 37 | { 38 | /// 39 | /// Account id 40 | /// 41 | public int id; 42 | 43 | /// 44 | /// Account type: cross-margin 45 | /// 46 | public string type; 47 | 48 | /// 49 | /// The margin loan pair 50 | /// 51 | public string symbol; 52 | 53 | /// 54 | /// Loan state 55 | /// Possible values: [created, accrual, cleared, invalid] 56 | /// 57 | public string state; 58 | 59 | /// 60 | /// The risk rate 61 | /// 62 | [JsonProperty("risk-rate")] 63 | public string riskRate; 64 | 65 | /// 66 | /// The price which triggers closeout 67 | /// 68 | [JsonProperty("fl-price")] 69 | public string flPrice; 70 | 71 | /// 72 | /// The list of margin accounts and their details 73 | /// 74 | public AccountDetail[] list; 75 | 76 | /// 77 | /// Currency detail 78 | /// 79 | public class AccountDetail 80 | { 81 | /// 82 | /// The currency of this balance 83 | /// 84 | public string currency; 85 | 86 | /// 87 | /// The balance type 88 | /// 89 | public string type; 90 | 91 | /// 92 | /// The balance in the main currency unit 93 | /// 94 | public string balance; 95 | } 96 | 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Huobi.SDK.Core/HttpRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Text; 3 | using System.Threading.Tasks; 4 | using Huobi.SDK.Core.Log; 5 | using Newtonsoft.Json; 6 | 7 | namespace Huobi.SDK.Core 8 | { 9 | /// 10 | /// The staic class that wrap the GET and POST Http request 11 | /// 12 | public class HttpRequest 13 | { 14 | //public static bool LogPerformanceEnabled = false; 15 | 16 | public static PerformanceLogger _logger = PerformanceLogger.GetInstance(); 17 | 18 | /// 19 | /// Send Http GET request 20 | /// 21 | /// The response type 22 | /// Request url 23 | /// The generic response type 24 | public static async Task GetAsync(string url) 25 | { 26 | var httpClient = new HttpClient(); 27 | 28 | _logger.RquestStart("GET", url); 29 | 30 | string response = await httpClient.GetStringAsync(url); 31 | 32 | _logger.RequestEnd(); 33 | 34 | T t = JsonConvert.DeserializeObject(response); 35 | 36 | return t; 37 | } 38 | 39 | /// 40 | /// Send Http GET request 41 | /// 42 | /// The response type 43 | /// Request url 44 | /// The generic response type 45 | public static async Task GetStringAsync(string url) 46 | { 47 | var httpClient = new HttpClient(); 48 | 49 | _logger.RquestStart("GET", url); 50 | 51 | string response = await httpClient.GetStringAsync(url); 52 | 53 | _logger.RequestEnd(); 54 | 55 | return response; 56 | } 57 | 58 | /// 59 | /// Send Http POST request 60 | /// 61 | /// The response type 62 | /// Request url 63 | /// Request body 64 | /// Meida type, default value is "application/json" 65 | /// The response type 66 | public static async Task PostAsync(string url, string body = null, string mediaTyp = "application/json") 67 | { 68 | StringContent httpContent; 69 | 70 | if (string.IsNullOrEmpty(body)) 71 | { 72 | httpContent = null; 73 | } 74 | else 75 | { 76 | httpContent = new StringContent(body, Encoding.UTF8, mediaTyp); 77 | } 78 | 79 | var httpClient = new HttpClient(); 80 | 81 | _logger.RquestStart("POST", url); 82 | 83 | var response = await httpClient.PostAsync(url, httpContent); 84 | 85 | string result = await response.Content.ReadAsStringAsync(); 86 | 87 | _logger.RequestEnd(); 88 | 89 | T t = JsonConvert.DeserializeObject(result); 90 | 91 | return t; 92 | } 93 | } 94 | } 95 | --------------------------------------------------------------------------------