using Knoks.Core.Entities; using Knoks.Core.Logic.Interfaces; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; namespace Knoks.Core.Exchanges { public class HUOBIExchange : IExchange { #region Members internal class TickerType { /* GET /market/detail?symbol=ethusdt */ /* { "status": "ok", "ch": "market.btcusdt.detail", "ts": 1489473538996, "tick": { "amount": 4316.4346, "open": 8090.54, "close": 7962.62, "high": 8119.00, "ts": 1489464451000, "id": 1489464451, "count": 9595, "low": 7875.00, "vol": 34497276.905760 } } */ public object this[string propertyName] { get { return this.GetType().GetProperty(propertyName).GetValue(this, null); } set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); } } public TickerItemType Tick { get; set; } [JsonProperty(PropertyName = "ts")] public long Timestamp { get; set; } } internal class TickerItemType { public object this[string propertyName] { get { return this.GetType().GetProperty(propertyName).GetValue(this, null); } set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); } } public decimal Low { get; set; } public decimal High { get; set; } [JsonProperty(PropertyName = "close")] public decimal Last { get; set; } [JsonProperty(PropertyName = "vol")] public decimal Volume { get; set; } } private ExchangeSettings settings; #endregion /// /// ctor /// /// public HUOBIExchange(ExchangeSettings settings) { this.settings = settings; this.settings.ApiUrl = settings.ApiUrl ?? "https://api.huobi.pro/"; // "https://api.hadax.com/"; } public async Task> GetMarkets() { HttpClient client = new HttpClient(); ///v1/common/symbols HttpResponseMessage response = await client.GetAsync(settings.ApiUrl + "v1/common/symbols"); if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsJsonAsync(); return data.Data.Where(s => settings.AllowedCurrencies.Contains(s.QuoteCurrency.ToUpper())). Select(it => new Ticker() { TickerDisplayName = $"{it.BaseCurrency.ToUpper()}/{it.QuoteCurrency.ToUpper()}", Currency1 = Replace(it.BaseCurrency.ToUpper()), Currency2 = Replace(it.QuoteCurrency.ToUpper()), Currency = Replace(it.BaseCurrency.ToUpper()), TickerSymbol = $"{it.BaseCurrency.ToUpper()}{it.QuoteCurrency.ToUpper()}" }); } throw new NotSupportedException("HUOBI error"); } public async Task GetTickerData(TickerInfo ticker, DateTime start, DateTime end) { ///market/detail?symbol=ethusdt HttpClient client = new HttpClient(); var response = await client.GetAsync($"{settings.ApiUrl}market/detail?symbol={ticker.Currency1.ToLower()}{ticker.Currency2.ToLower()}"); if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsJsonAsync(); return new TickerData() { TickerTime = ConvertFromLong(data.Timestamp), TickerId = ticker.TickerId, Open = data.Tick.Low, High = data.Tick.High, Low = data.Tick.Low, Close = data.Tick.Last, Volume = data.Tick.Volume }; } throw new NotSupportedException("HUOBI error"); } #region Helpers private long ConvertToLong(DateTime time) { return (long)(time - Constants._1970Time).TotalMilliseconds; } private DateTime ConvertFromLong(long ms) { return Constants._1970Time.AddMilliseconds(ms); } private string Replace(string asset) { if (settings.ReplaceSymbols != null && settings.ReplaceSymbols.ContainsKey(asset)) { return settings.ReplaceSymbols[asset]; } return asset; } #endregion } }