134 lines
4.9 KiB
C#
134 lines
4.9 KiB
C#
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
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
/// <param name="settings"></param>
|
|
public HUOBIExchange(ExchangeSettings settings)
|
|
{
|
|
this.settings = settings;
|
|
this.settings.ApiUrl = settings.ApiUrl ?? "https://api.huobi.pro/"; // "https://api.hadax.com/";
|
|
}
|
|
|
|
public async Task<IEnumerable<Ticker>> 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<HUOBIResponse>();
|
|
|
|
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<TickerData> 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<TickerType>();
|
|
|
|
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
|
|
}
|
|
}
|