208 lines
6.5 KiB
C#
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
|
|
}
|
|
}
|