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 BitfinexExchange : IExchange { #region Members internal class TickerType { public object this[string propertyName] { get { return this.GetType().GetProperty(propertyName).GetValue(this, null); } set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); } } /* 0{"mid":"0.069812", 1"bid":"0.069791", 2"ask":"0.069833", 3"last_price":"0.069791", 4"low":"0.068682", 5"high":"0.070229", 6"volume":"7313.0993800100005", 7"timestamp":"1531400781.645441"} */ public decimal Mid { get; set; } [JsonIgnore] public decimal Bid { get; set; } [JsonIgnore] public decimal Ask { get; set; } public decimal Last_price { get; set; } public decimal Low { get; set; } public decimal High { get; set; } public decimal Volume { get; set; } public decimal Timestamp { get; set; } } private ExchangeSettings settings; #endregion /// /// ctor /// /// public BitfinexExchange(ExchangeSettings settings) { this.settings = settings; this.settings.ApiUrl = settings.ApiUrl ?? "https://api.bitfinex.com/"; } public async Task> GetMarkets() { //var handler = new HttpClientHandler(); //handler.ClientCertificateOptions = ClientCertificateOption.Manual; //handler.ServerCertificateCustomValidationCallback = //(httpRequestMessage, cert, cetChain, policyErrors) => //{ // return true; //}; //ServicePointManager.ServerCertificateValidationCallback = // new RemoteCertificateValidationCallback( // delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) // { // return true; // }); HttpClient client = new HttpClient(); HttpResponseMessage response = await client.GetAsync(settings.ApiUrl + "v1/symbols");//https://api.bitfinex.com/v1/symbols if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsJsonAsync>(); var parse = data.Select(it => new Tuple(it.Substring(0, 3).ToUpper(), it.Substring(3, 3).ToUpper())); return parse.Where(s => settings.AllowedCurrencies.Contains(s.Item2.ToUpper())) .Select(it => new Ticker() { TickerDisplayName = $"{it.Item1}/{it.Item2}", Currency1 = Replace(it.Item1), Currency2 = Replace(it.Item2), Currency = Replace(it.Item1), TickerSymbol = it.Item1 + it.Item2 });//Active } throw new NotSupportedException("Bitfinex error"); } public async Task GetTickerData(TickerInfo ticker, DateTime start, DateTime end) { HttpClient client = new HttpClient(); var response = await client.GetAsync($"{settings.ApiUrl}v1/pubticker/{ticker.TickerSymbol}"); if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsJsonAsync(); return new TickerData() { TickerTime = DateTime.UtcNow, // ConvertFromLong(Decimal.ToInt32(data.Timestamp)), TickerId = ticker.TickerId, Open = data.Low, High = data.High, Low = data.Low, Close = data.Last_price, Volume = data.Volume }; } throw new NotSupportedException("Bitfinex error"); } #region Helpers private DateTime ConvertFromLong(long ms) { return new DateTime(DateTime.UtcNow.Date.Millisecond + ms); } private string Replace(string asset) { if (settings.ReplaceSymbols != null && settings.ReplaceSymbols.ContainsKey(asset)) { return settings.ReplaceSymbols[asset]; } return asset; } #endregion } }