238 lines
7.7 KiB
C#
238 lines
7.7 KiB
C#
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using WebSocket.Interfaces;
|
|
using System.Linq;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Text;
|
|
|
|
namespace WebSocket.Clients
|
|
{
|
|
public class HUOBIClient : IWebClient
|
|
{
|
|
#region Members
|
|
internal class HUOBIResponse
|
|
{
|
|
[JsonProperty(PropertyName = "ts")]
|
|
public long Timestamp { get; set; }
|
|
public HUOBIMarket Tick { get; set; }
|
|
[JsonProperty(PropertyName = "ch")]
|
|
public string Name { get; set; }
|
|
public string Pair {
|
|
get {
|
|
var array = this.Name.Split('.');
|
|
return array.Length > 1 ? array[1].ToUpper() : string.Empty;
|
|
}
|
|
set { }
|
|
}
|
|
}
|
|
|
|
internal class HUOBIMarket
|
|
{
|
|
[JsonProperty(PropertyName = "open")]
|
|
public decimal Open { get; set; }
|
|
[JsonProperty(PropertyName = "close")]
|
|
public decimal Close { get; set; }
|
|
[JsonProperty(PropertyName = "low")]
|
|
public decimal Low { get; set; }
|
|
[JsonProperty(PropertyName = "high")]
|
|
public decimal High { get; set; }
|
|
[JsonProperty(PropertyName = "vol")]
|
|
public decimal Volume { get; set; }
|
|
//ts":1535719364915,
|
|
//"tick":{"id":1535719320,"open":0.000029570000000000,"close":0.000029630000000000,
|
|
// "low":0.000029570000000000,"high":0.000029630000000000,
|
|
// "amount":16.450000000000000000,"vol":0.000487268300000000000000000000000000,"count":2}}
|
|
}
|
|
private IWebSocketForClient server;
|
|
private Dictionary<string, Action<Command, string>> CommandAnswers = new Dictionary<string, Action<Command, string>>();
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
public HUOBIClient(IWebSocketForClient server)
|
|
{
|
|
this.server = server;
|
|
Register();
|
|
}
|
|
|
|
public void Connected()
|
|
{
|
|
//SendAuth();
|
|
//wait connected message?
|
|
}
|
|
|
|
public void StartRequest(string[] pairs) {
|
|
Send(new { sub = $"market.{pairs[0].ToLower()}.kline.1min", id = $"id{1}" });
|
|
//Send(new {
|
|
// req = $"\"market.ethbtc.kline.1min\"",
|
|
// id = $"\"id10\""
|
|
//});
|
|
|
|
//server.Send($"{{\"sub\":\"market.{pairs[0].ToLower()}.kline.1min\", \"id\":\"id10\"}}");
|
|
//{
|
|
// "req": "market.ethbtc.kline.1min",
|
|
// "id": "id10"
|
|
//}
|
|
}
|
|
|
|
private void Register()
|
|
{
|
|
On("connected", (c, obj) => Connected());
|
|
On("ping", (c, obj) => SendPong());
|
|
//On("ohlcv1m", (c, obj) => Update(c.E, c, obj, typeof(Summary)));
|
|
}
|
|
|
|
public void Message(string message)
|
|
{
|
|
var parse = JsonConvert.DeserializeObject<Command>(message, GetSettings());
|
|
if (parse.Oid != null && CommandAnswers.ContainsKey(parse.E + parse.Oid))
|
|
{
|
|
CommandAnswers[parse.E + parse.Oid](parse, message);
|
|
}
|
|
if (CommandAnswers.ContainsKey(parse.E))
|
|
{
|
|
CommandAnswers[parse.E](parse, message);
|
|
}
|
|
/*
|
|
// response
|
|
{
|
|
"status": "ok",
|
|
"rep": "market.btccny.kline.1min",
|
|
"tick": [
|
|
{
|
|
"amount": 1.6206,
|
|
"count": 3,
|
|
"id": 1494465840,
|
|
"open": 9887.00,
|
|
"close": 9885.00,
|
|
"low": 9885.00,
|
|
"high": 9887.00,
|
|
"vol": 16021.632026
|
|
},
|
|
{
|
|
"amount": 2.2124,
|
|
"count": 6,
|
|
"id": 1494465900,
|
|
"open": 9885.00,
|
|
"close": 9880.00,
|
|
"low": 9880.00,
|
|
"high": 9885.00,
|
|
"vol": 21859.023500
|
|
}
|
|
]
|
|
}
|
|
*/
|
|
}
|
|
|
|
public void Tick()
|
|
{
|
|
//'ticker' or 'get-balance'
|
|
}
|
|
|
|
public void Data(byte[] data)
|
|
{
|
|
using (var compressedStream = new MemoryStream(data))
|
|
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
|
|
using (var resultStream = new MemoryStream())
|
|
{
|
|
zipStream.CopyTo(resultStream);
|
|
var tickData = JsonConvert.DeserializeObject(Encoding.Default.GetString(resultStream.ToArray()), typeof(HUOBIResponse), GetSettings()) as HUOBIResponse;
|
|
if (tickData.Tick != null)
|
|
{
|
|
//this.server.updateData.Invoke(server.ExchangeId, "HUOBI", GetMarketOHLCVData(new Dictionary<string, object> { { tickData.Pair, tickData } }));
|
|
this.server.DataChanged("HUOBI", GetMarketOHLCVData(new Dictionary<string, object> { { tickData.Pair, tickData } }));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Data(Dictionary<string, object> data)
|
|
{
|
|
}
|
|
|
|
public void Closed(bool byUser, string reason)
|
|
{
|
|
//{"unsub": "market.btccny.trade.detail", "id": "id4"}
|
|
}
|
|
|
|
public void Error(Exception ex)
|
|
{
|
|
}
|
|
|
|
public void Error(string reason)
|
|
{
|
|
}
|
|
|
|
public void SendFailed(string data, Exception ex)
|
|
{
|
|
}
|
|
|
|
private void Send(object obj)
|
|
{
|
|
server.Send(JsonConvert.SerializeObject(obj, GetSettings()));
|
|
}
|
|
|
|
private void SendPong()
|
|
{
|
|
Send(new Command() { E = "pong" });
|
|
}
|
|
|
|
private void On(string name, Action<Command, string> command)
|
|
{
|
|
CommandAnswers[name] = command;
|
|
}
|
|
|
|
private void Off(string name)
|
|
{
|
|
if (CommandAnswers.ContainsKey(name))
|
|
{
|
|
CommandAnswers.Remove(name);
|
|
}
|
|
}
|
|
|
|
public Dictionary<string, IMarketOHLCVData> GetMarketOHLCVData(Dictionary<string, object> data)
|
|
{
|
|
return data.Select(x =>
|
|
{
|
|
var item = x.Value as HUOBIResponse;
|
|
return new MarketOHLCVData()
|
|
{
|
|
PairSymbol = item.Pair,
|
|
HighPrice = item.Tick.High,
|
|
LowPrice = item.Tick.Low,
|
|
OpenPrice = item.Tick.Open,
|
|
ClosePrice = item.Tick.Close,
|
|
Volume = item.Tick.Volume,
|
|
TimeStamp = ConvertFromLong(item.Timestamp),
|
|
} as IMarketOHLCVData;
|
|
}).ToDictionary(x => x.PairSymbol);
|
|
}
|
|
|
|
#region Helpers
|
|
private DateTime _1970Time = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
private long ConvertToLong(DateTime time)
|
|
{
|
|
return (long)(time - _1970Time).TotalMilliseconds;
|
|
}
|
|
private DateTime ConvertFromLong(long ms)
|
|
{
|
|
return _1970Time.AddMilliseconds(ms);
|
|
}
|
|
|
|
private JsonSerializerSettings GetSettings()
|
|
{
|
|
var settings = new JsonSerializerSettings()
|
|
{
|
|
ContractResolver = new LowerCaseUnderscoreContractResolver()
|
|
//Formatting = Formatting.Indented
|
|
};
|
|
settings.Converters.Add(new Newtonsoft.Json.Converters.UnixDateTimeConverter());
|
|
return settings;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|