Skip to content

Commit 9e14991

Browse files
authored
add trade stream to LBank (#741)
1 parent 8c8c707 commit 9e14991

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

src/ExchangeSharp/API/Exchanges/LBank/ExchangeLBankAPI.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public class ExchangeLBankAPI : ExchangeAPI
3939
/// </summary>
4040
public override string BaseUrl { get; set; } = "https://api.lbank.info/v1";
4141

42+
public override string BaseUrlWebSocket { get; set; } = "wss://www.lbkex.net/ws/V2/";
43+
4244
/// <summary>
4345
/// Gets the name of the API.
4446
/// </summary>
@@ -539,6 +541,63 @@ private List<ExchangeWithdrawalResponse> ParseWithdrawListResponse(JToken withdr
539541

540542
#endregion PARSERS PrivateAPI
541543

544+
#region Websockets
545+
protected override async Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValuePair<string, ExchangeTrade>, Task> callback, params string[] marketSymbols)
546+
{
547+
if (marketSymbols == null || marketSymbols.Length == 0)
548+
{
549+
marketSymbols = (await GetMarketSymbolsAsync()).ToArray();
550+
}
551+
return await ConnectPublicWebSocketAsync("", async (_socket, msg) =>
552+
{
553+
/* {
554+
"trade":{
555+
"volume":6.3607,
556+
"amount":77148.9303,
557+
"price":12129,
558+
"direction":"sell",
559+
"TS":"2019-06-28T19:55:49.460"
560+
},
561+
"type":"trade",
562+
"pair":"btc_usdt",
563+
"SERVER":"V2",
564+
"TS":"2019-06-28T19:55:49.466"
565+
}*/
566+
JToken token = JToken.Parse(msg.ToStringFromUTF8());
567+
if (token["status"].ToStringInvariant() == "error")
568+
{
569+
if (token["message"].ToStringInvariant().Contains("Invalid order pairs"))
570+
{
571+
// ignore, bc invalid order pairs are normal in LBank
572+
}
573+
else throw new APIException(token["message"].ToStringInvariant());
574+
}
575+
else if (token["type"].ToStringInvariant() == "trade")
576+
{
577+
var trade = token["trade"].ParseTrade("amount", "price", "direction", "TS", TimestampType.Iso8601China, null);
578+
string marketSymbol = token["pair"].ToStringInvariant();
579+
await callback(new KeyValuePair<string, ExchangeTrade>(marketSymbol, trade));
580+
}
581+
}, async (_socket) =>
582+
{ /* {
583+
"action":"subscribe",
584+
"subscribe":"trade",
585+
"pair":"eth_btc"
586+
}*/
587+
foreach (var marketSymbol in marketSymbols)
588+
{
589+
var subscribeRequest = new
590+
{
591+
action = "subscribe",
592+
subscribe = "trade",
593+
pair = marketSymbol,
594+
};
595+
await _socket.SendMessageAsync(subscribeRequest);
596+
}
597+
});
598+
}
599+
#endregion
600+
542601
#region HELPERS
543602

544603
protected override async Task ProcessRequestAsync(IHttpWebRequest request, Dictionary<string, object> payload)

src/ExchangeSharp/Utility/CryptoUtility.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public static class CryptoUtility
3838
internal static readonly DateTime UnixEpochLocal = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local);
3939
internal static readonly Encoding Utf8EncodingNoPrefix = new UTF8Encoding(false, true);
4040
static bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
41+
static string chinaZoneId = isWindows ? "China Standard Time" : "Asia/Shanghai";
42+
static TimeZoneInfo chinaZone = TimeZoneInfo.FindSystemTimeZoneById(chinaZoneId);
4143
static string koreanZoneId = isWindows ? "Korea Standard Time" : "Asia/Seoul";
4244
static TimeZoneInfo koreaZone = TimeZoneInfo.FindSystemTimeZoneById(koreanZoneId);
4345

@@ -188,7 +190,7 @@ public enum SourceTimeZone
188190
{
189191
/// <summary> time zone is specifically specified in string </summary>
190192
AsSpecified,
191-
Local, Korea, UTC
193+
Local, China, Korea, UTC,
192194
}
193195
/// <summary>
194196
/// Convert object to a UTC DateTime
@@ -215,6 +217,8 @@ public static DateTime ToDateTimeInvariant(this object obj, SourceTimeZone sourc
215217
throw new NotImplementedException(); // TODO: implement this when needed
216218
case SourceTimeZone.Local:
217219
return DateTime.SpecifyKind(dt, DateTimeKind.Local).ToUniversalTime(); // convert to UTC
220+
case SourceTimeZone.China:
221+
return TimeZoneInfo.ConvertTime(dt, chinaZone, TimeZoneInfo.Utc); // convert to UTC
218222
case SourceTimeZone.Korea:
219223
return TimeZoneInfo.ConvertTime(dt, koreaZone, TimeZoneInfo.Utc); // convert to UTC
220224
case SourceTimeZone.UTC:
@@ -693,6 +697,9 @@ public static DateTime ParseTimestamp(object value, TimestampType type)
693697
case TimestampType.Iso8601Local:
694698
return value.ToDateTimeInvariant(SourceTimeZone.Local);
695699

700+
case TimestampType.Iso8601China:
701+
return value.ToDateTimeInvariant(SourceTimeZone.China);
702+
696703
case TimestampType.Iso8601Korea:
697704
return value.ToDateTimeInvariant(SourceTimeZone.Korea);
698705

@@ -1481,6 +1488,11 @@ public enum TimestampType
14811488
/// </summary>
14821489
Iso8601Local,
14831490

1491+
/// <summary>
1492+
/// ISO 8601 in china Standard Time
1493+
/// </summary>
1494+
Iso8601China,
1495+
14841496
/// <summary>
14851497
/// ISO 8601 in Korea Standard Time
14861498
/// </summary>

0 commit comments

Comments
 (0)