using Knoks.Core.Data.Dao; using Knoks.Core.Data.Interfaces; using Knoks.Core.Entities; using Knoks.Core.Logic.Interfaces; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace Knoks.Core.Logic.Managers { public class ExchangeManager : IExchangeManager { private readonly ILogger _logger; private readonly IExchangeDao _exchangeDao; private readonly IDictionary _exchanges; private readonly IKnokSettings _settings; public ExchangeManager(ILogger logger, IExchangeDao exchangeDao, IKnokSettings _settings, IDictionary exchanges) { this._exchangeDao = exchangeDao; this._exchanges = exchanges; this._settings = _settings; this._logger = logger; } public async Task UpdateExchanges() { System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; if (System.Net.ServicePointManager.ServerCertificateValidationCallback == null) { System.Net.ServicePointManager.ServerCertificateValidationCallback = ((s, c, c2, se) => true); } await Task.WhenAll(_exchanges.Select(async it => { try { var data = await it.Value.GetMarkets(); await _exchangeDao.SaveTickers(it.Key, data); } catch (Exception ex) { this._logger.LogError(ex, $"UpdateExchanges error for ExchangeId: {it.Key}"); } })); } public async Task GetTradingPairRate(int exchangeId, string currency1, string currency2) { System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; if (System.Net.ServicePointManager.ServerCertificateValidationCallback == null) { System.Net.ServicePointManager.ServerCertificateValidationCallback = ((s, c, c2, se) => true); } return await Task.Run(() => { try { TickerInfo ticker = _exchangeDao.GetTicker(exchangeId, currency1, currency2).GetAwaiter().GetResult(); var exchange = _exchanges[ticker.ExchangeId]; var tickerData = exchange.GetTickerData(ticker, DateTime.UtcNow.AddMinutes(-15), DateTime.UtcNow.AddMinutes(15)).GetAwaiter().GetResult(); if (tickerData != null) { var minVal = (decimal)(1 / Math.Pow(10, ticker.Decimals)); var exchangeStart = new ExchangeStart(); //1.Entry from = current price from the relevant exchange var val = tickerData.Close ?? 0m; exchangeStart.EntryFrom = val; //2.Entry to = Entry from + minimum spread for entry(%) val = Math.Round( val + ((val / 100m) * _settings.MinEntrySpread), ticker.Decimals); exchangeStart.EntryTo = val; //3.Exit from = Entry to + minimum high spread for entry (%) val = Math.Round(val + ((val / 100m) * _settings.MinHighEntrySpread), ticker.Decimals); exchangeStart.ExitFrom = val; //4.Exit to = Exit from + minimum spread for exit (%) val = Math.Round(val + ((val / 100m) * _settings.MinExitSpread), ticker.Decimals); exchangeStart.ExitTo = val; //5.SL = Entry from - highest possible SL val = Math.Round( (tickerData.Close ?? 0m) - minVal, ticker.Decimals); exchangeStart.StopLoss = val; exchangeStart.Precision = (short)ticker.Decimals; return exchangeStart; } return new ExchangeStart(); } catch(Exception ex) { this._logger.LogError(ex, $"GetTradingPairRate error for ExchangeId: {exchangeId}. Pair: \"{currency1}-{currency2}\""); return new ExchangeStart(); } }); } public async Task PutDataExchanges(TickerData data) { await _exchangeDao.SaveExchanges(data); } /*public async Task UpdateTickers() { GetUsedInKnoksTickers RequestTickerData }*/ public async Task GetTickerData(int tickerId, DateTime start, DateTime end) { try { TickerInfo ticker = await _exchangeDao.GetTicker(tickerId); var exchange = _exchanges[ticker.ExchangeId]; return await exchange.GetTickerData(ticker, start, end); } catch (Exception ex) { this._logger.LogError(ex, $"GetTickerData error for TickerId: {tickerId}. Date: \"{start}-{end}\""); return new TickerData(); } } public async Task GetTickerData(int exchangeId, string currency1, string currency2) { try { TickerInfo ticker = await _exchangeDao.GetTicker(exchangeId, currency1, currency2); var exchange = _exchanges[ticker.ExchangeId]; return await exchange.GetTickerData(ticker, DateTime.UtcNow.AddMinutes(-15), DateTime.UtcNow.AddMinutes(15)); } catch (Exception ex) { this._logger.LogError(ex, $"GetTickerData error for ExchangeId: {exchangeId}. Pair: \"{currency1}-{currency2}\""); return new TickerData(); } } /*public async Task> RequestTickerData(int tickerId, DateTime start, DateTime end) { TickerInfo ticker = await exchangeDao.GetTicker(tickerId); var exchange = exchanges[ticker.ExchangeId]; if (ticker.TickerActive && ticker.TickerEnd < start) { if (ticker.TickerGot != ticker.TickerEnd) { Save(await exchange.GetTickerData(ticker, ticker.TickerGot, ticker.TickerEnd)); //ticker.TickerGot = ticker.TickerEnd; ticker.TickerStart = ticker.TickerGot = start; ticker.TickerEnd = end; } } DateTime loadStart; if (ticker.TickerActive) { loadStart = new List() { ticker.TickerGot, start }.Min(); } else { ticker.TickerActive = true; loadStart = ticker.TickerStart = ticker.TickerGot = start; ticker.TickerEnd = new List() { ticker.TickerEnd, end }.Max(); } Save(await exchange.GetTickerData(ticker, loadStart, new List() { ticker.TickerEnd, DateTime.UtcNow }.Min()); if (ticker.TickerEnd < DateTime.UtcNow) { ticker.TickerActive = false; } //tickerSave //exchangeDao.SaveTickerInfo(); } private void Save(IEnumerable data) { var list = data.ToList(); foreach (var val in list) { exchangeDao.SaveTickerData(val); } } */ } }