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 OKExExchange : IExchange { #region Members internal class TickerType { /* {"date":"1535960855", "ticker":{"high":7320,"vol":3276506,"day_high":0,"last":7227.22, "low":7181.84,"contract_id":201809070000034,"buy":7228.56,"sell":7231.02, "coin_vol":0,"day_low":0,"unit_amount":100}} */ 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 Ticker { get; set; } [JsonProperty(PropertyName = "date")] 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 = "last")] public decimal Last { get; set; } [JsonProperty(PropertyName = "vol")] public decimal Volume { get; set; } } private ExchangeSettings settings; #endregion /// /// ctor /// /// public OKExExchange(ExchangeSettings settings) { this.settings = settings; this.settings.ApiUrl = settings.ApiUrl ?? "https://www.okex.com/api/v1/"; } public async Task> GetMarkets() { HttpClient client = new HttpClient(); HttpResponseMessage response = await client.GetAsync(settings.ApiUrl + "tickers.do"); if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsJsonAsync(); return data.Tickers.Where(s => settings.AllowedCurrencies.Contains(s.NoneBaseCurrency.ToUpper())). Select(it => new Ticker() { TickerDisplayName = $"{it.BaseCurrency.ToUpper()}/{it.NoneBaseCurrency.ToUpper()}", Currency1 = Replace(it.BaseCurrency.ToUpper()), Currency2 = Replace(it.NoneBaseCurrency.ToUpper()), Currency = Replace(it.BaseCurrency.ToUpper()), TickerSymbol = $"{it.BaseCurrency.ToUpper()}{it.NoneBaseCurrency.ToUpper()}" }); } throw new NotSupportedException("OKEx error"); } public async Task GetTickerData(TickerInfo ticker, DateTime start, DateTime end) { HttpClient client = new HttpClient(); var response = await client.GetAsync($"{settings.ApiUrl}ticker.do?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.Ticker.Low, High = data.Ticker.High, Low = data.Ticker.Low, Close = data.Ticker.Last, Volume = data.Ticker.Volume }; } throw new NotSupportedException("OKEx 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 } }