Knocks/BackEnd/WebSocket.Clients/Clients/OKExClient.cs

208 lines
6.5 KiB
C#

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using WebSocket.Interfaces;
using System.Linq;
using System.IO;
using System.Text;
using Newtonsoft.Json.Linq;
namespace WebSocket.Clients
{
public class OKExClient : IWebClient
{
#region Members
internal class OKExResponse
{
[JsonProperty(PropertyName = "channel")]
public string Channel { get; set; }
public int Binary { get; set; }
public string Pair {
get {
var arr = this.Channel.Split('_');
if (arr.Length > 4)
{
return arr[3].ToUpper() + arr[4].ToUpper();
}
return string.Empty;
}
set { } }
}
internal class OKExResponse2: OKExResponse
{
[JsonProperty(PropertyName = "data")]
public JValue[][] Data { get; set; }
}
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 OKExClient(IWebSocketForClient server)
{
this.server = server;
Register();
}
public void Connected()
{
//SendAuth();
//wait connected message?
}
public void StartRequest(string[] pairs) {
//Send(new [] { new { Event = "addChannel", Channel = $"ok_sub_spot_{pairs[0].ToLower()}_kline_1min" }});
server.Send($"[{{'event':'addChannel','channel':'ok_sub_spot_{pairs[0].ToLower()}_kline_1min'}}]");
}
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<IEnumerable<OKExResponse>>(message, GetSettings());
var data = parse.FirstOrDefault();
if (data != null)
{
if (data.Channel.StartsWith("ok_sub_spot"))
{
dynamic jsonDe = JsonConvert.DeserializeObject(message, GetSettings());
if (jsonDe is JArray && jsonDe.Count > 0)
{
var rawData = jsonDe[0];
if (rawData != null && rawData.data is JArray)
{
var parse2 = JsonConvert.DeserializeObject<IEnumerable<OKExResponse2>>(message, GetSettings());
var data2 = parse2.FirstOrDefault();
if (data2 != null)
{
this.server.DataChanged("OKEx", GetMarketOHLCVData(new Dictionary<string, object> { { data2.Pair, data2 } }));
}
}
}
}
}
}
public void Tick()
{
//'ticker' or 'get-balance'
}
public void Data(byte[] data)
{
}
public void Data(Dictionary<string, object> data)
{
}
public void Closed(bool byUser, string reason)
{
}
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 OKExResponse2;
var itemData = item.Data[0];
if (itemData != null)
{
//[time, open price, highest price, lowest price, close price, volume]
//[string, string, string, string, string, string]
return new MarketOHLCVData()
{
TimeStamp = ConvertFromLong(itemData[0].ToObject<long>()),
OpenPrice = itemData[1].ToObject<decimal>(),
HighPrice = itemData[2].ToObject<decimal>(),
LowPrice = itemData[3].ToObject<decimal>(),
ClosePrice = itemData[4].ToObject<decimal>(),
Volume = itemData[5].ToObject<decimal>(),
PairSymbol = x.Key
} as IMarketOHLCVData;
}
else {
return null;
}
}).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;
}
//private static bool IsPropertyExist(dynamic settings, string name)
//{
// if (settings is ExpandoObject)
// return ((IDictionary<string, object>)settings).ContainsKey(name);
// return settings.GetType().GetProperty(name) != null;
//}
#endregion
}
}