262 lines
9.3 KiB
C#
262 lines
9.3 KiB
C#
//using Cex.Models;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Converters;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using WebSocket.Interfaces;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Globalization;
|
|
using System.Text.RegularExpressions;
|
|
using Newtonsoft.Json.Serialization;
|
|
using Newtonsoft.Json.Linq;
|
|
using System.IO;
|
|
|
|
namespace WebSocket.Clients
|
|
{
|
|
public class LowerCaseUnderscoreContractResolver : DefaultContractResolver
|
|
{
|
|
private Regex regex = new Regex("(?!(^[A-Z]))([A-Z])");
|
|
|
|
protected override string ResolvePropertyName(string propertyName)
|
|
{
|
|
return regex.Replace(propertyName, "_$2"); //.ToLower();
|
|
}
|
|
}
|
|
|
|
public class MicrosoftSecondsDateTimeConverter : DateTimeConverterBase
|
|
{
|
|
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
{
|
|
if (reader.TokenType == JsonToken.Null)
|
|
return null;
|
|
|
|
var token = JToken.Load(reader);
|
|
if (token.Type == JTokenType.Integer)
|
|
{
|
|
var dt = epoch.AddMilliseconds((long)token);
|
|
return dt;
|
|
}
|
|
|
|
// Not a Microsoft date.
|
|
return new JsonSerializer().Deserialize(token.CreateReader(), objectType);
|
|
}
|
|
|
|
public override bool CanWrite { get { return false; } }
|
|
|
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
public class BinanceStreamModel
|
|
{
|
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
public string e { get; set; }
|
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
public string E { get; set; }
|
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
public string s { get; set; }
|
|
[JsonProperty("k", NullValueHandling = NullValueHandling.Ignore)]
|
|
public BinanceTickerData Data { get; set; }
|
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Ok { get; set; }
|
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Error { get; set; }
|
|
}
|
|
|
|
public class BinanceTickerData
|
|
{
|
|
[JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)]
|
|
[JsonConverter(typeof(MicrosoftSecondsDateTimeConverter))]
|
|
public DateTime StartTime { get; set; } // : 123400000, // Kline start time
|
|
[JsonProperty("T", NullValueHandling = NullValueHandling.Ignore)]
|
|
[JsonConverter(typeof(MicrosoftSecondsDateTimeConverter))]
|
|
public DateTime CloseTime { get; set; } //"T": 123460000, // Kline close time
|
|
[JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)]
|
|
public string Symbol { get; set; } // "s": "BNBBTC", // Symbol
|
|
[JsonProperty("o", NullValueHandling = NullValueHandling.Ignore)]
|
|
public decimal OpenPrice { get; set; } // "o": "0.0010", // Open price
|
|
[JsonProperty("c", NullValueHandling = NullValueHandling.Ignore)]
|
|
public decimal ClosePrice { get; set; } // "c": "0.0020", // Close price
|
|
[JsonProperty("h", NullValueHandling = NullValueHandling.Ignore)]
|
|
public decimal HighPrice { get; set; } // "h": "0.0025", // High price
|
|
[JsonProperty("l", NullValueHandling = NullValueHandling.Ignore)]
|
|
public decimal LowPrice { get; set; } // "l": "0.0015", // Low price
|
|
[JsonProperty("v", NullValueHandling = NullValueHandling.Ignore)]
|
|
public decimal Volume { get; set; } // "v": "1000", // Base asset volume
|
|
|
|
// "i": "1m", // Interval
|
|
// "f": 100, // First trade ID
|
|
// "L": 200, // Last trade ID
|
|
// "n": 100, // Number of trades
|
|
// "x": false, // Is this kline closed?
|
|
// "q": "1.0000", // Quote asset volume
|
|
// "V": "500", // Taker buy base asset volume
|
|
// "Q": "0.500", // Taker buy quote asset volume
|
|
// "B": "123456" // Ignore
|
|
// }
|
|
}
|
|
|
|
public class BinanceModel: Command
|
|
{
|
|
public string stream { get; set; }
|
|
public BinanceStreamModel data { get; set; }
|
|
|
|
//"e": "kline", // Event type
|
|
//"E": 123456789, // Event time
|
|
//"s": "BNBBTC", // Symbol
|
|
//"k": {
|
|
// "t": 123400000, // Kline start time
|
|
// "T": 123460000, // Kline close time
|
|
// "s": "BNBBTC", // Symbol
|
|
// "i": "1m", // Interval
|
|
// "f": 100, // First trade ID
|
|
// "L": 200, // Last trade ID
|
|
// "o": "0.0010", // Open price
|
|
// "c": "0.0020", // Close price
|
|
// "h": "0.0025", // High price
|
|
// "l": "0.0015", // Low price
|
|
// "v": "1000", // Base asset volume
|
|
// "n": 100, // Number of trades
|
|
// "x": false, // Is this kline closed?
|
|
// "q": "1.0000", // Quote asset volume
|
|
// "V": "500", // Taker buy base asset volume
|
|
// "Q": "0.500", // Taker buy quote asset volume
|
|
// "B": "123456" // Ignore
|
|
// }
|
|
}
|
|
|
|
public class BinanceClient : IWebClient
|
|
{
|
|
#region Members
|
|
//private Dictionary<string, object> data = new Dictionary<string, object>();
|
|
private Dictionary<string, Action<Command, string>> CommandAnswers = new Dictionary<string, Action<Command, string>>();
|
|
private IWebSocketForClient server;
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
public BinanceClient(IWebSocketForClient server)
|
|
{
|
|
this.server = server;
|
|
Register();
|
|
}
|
|
|
|
public void Connected()
|
|
{
|
|
//SendAuth();
|
|
//wait connected message?
|
|
}
|
|
|
|
private void Update(string name, Command command, string message, Type dataType) {
|
|
var data = new Dictionary<string, object>();
|
|
data[name]= JsonConvert.DeserializeObject(message, dataType, GetSettings());
|
|
this.server.DataChanged("Binance", GetMarketOHLCVData(data));
|
|
//this.server.updateData.Invoke(this.server.ExchangeId, "Binance", GetMarketOHLCVData(data));
|
|
}
|
|
|
|
private void Register()
|
|
{
|
|
On("kline", (c, obj) => Update(((BinanceModel)c).stream, c, obj, typeof(BinanceModel)));
|
|
//On("connected", (c, obj) => SendAuth());
|
|
//On("auth", (c, obj) => { if (c.Ok != null) { SetSubscribes(); } });
|
|
On("ping", (c, obj) => SendPong());
|
|
}
|
|
|
|
public void Message(string message)
|
|
{
|
|
var parse = JsonConvert.DeserializeObject<BinanceModel>(message, GetSettings());
|
|
//var arg = ((BinanceModel)parse);
|
|
if (parse.data != null && CommandAnswers.ContainsKey(parse.data.e))
|
|
{
|
|
CommandAnswers[parse.data.e](parse, message);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
//subscribed = false;
|
|
}
|
|
|
|
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 => new MarketOHLCVData()
|
|
{
|
|
PairSymbol = ((BinanceModel)x.Value).data.s,
|
|
HighPrice = ((BinanceModel)x.Value).data.Data.HighPrice,
|
|
LowPrice = ((BinanceModel)x.Value).data.Data.LowPrice,
|
|
OpenPrice = ((BinanceModel)x.Value).data.Data.OpenPrice,
|
|
ClosePrice = ((BinanceModel)x.Value).data.Data.ClosePrice,
|
|
Volume = ((BinanceModel)x.Value).data.Data.Volume,
|
|
TimeStamp = ((BinanceModel)x.Value).data.Data.CloseTime
|
|
} as IMarketOHLCVData).ToDictionary(x => x.PairSymbol);
|
|
}
|
|
|
|
private JsonSerializerSettings GetSettings()
|
|
{
|
|
var settings = new JsonSerializerSettings()
|
|
{
|
|
ContractResolver = new LowerCaseUnderscoreContractResolver()
|
|
//Formatting = Formatting.Indented
|
|
};
|
|
//settings.Converters.Add(new MicrosoftSecondsDateTimeConverter());
|
|
return settings;
|
|
}
|
|
}
|
|
}
|