using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Core.Main; using Core.Helper; using Core.Main.DataObjects.PTMagicData; using Newtonsoft.Json; namespace Core.MarketAnalyzer { public class CoinMarketCap : BaseAnalyzer { public static string GetMarketData(PTMagicConfiguration systemConfiguration, LogHelper log) { string result = ""; try { string baseUrl = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=200"; string cmcAPI = systemConfiguration.GeneralSettings.Application.CoinMarketCapAPIKey; log.DoLogInfo("CoinMarketCap - Getting market data..."); Dictionary jsonObject = GetJsonFromURL(baseUrl, log, cmcAPI); if (jsonObject.Count > 0) { if (jsonObject["data"] != null) { log.DoLogInfo("CoinMarketCap - Market data received for " + jsonObject["data"].Count + " currencies"); Dictionary markets = new Dictionary(); for (int i = 0; i < jsonObject["data"].Count; i++) { if (jsonObject["data"][i]["quote"]["USD"] != null) { Market market = new Market(); market.Position = markets.Count + 1; market.Name = jsonObject["data"][i]["name"].ToString(); market.Symbol = jsonObject["data"][i]["symbol"].ToString(); market.Price = (double)jsonObject["data"][i]["quote"]["USD"]["price"]; market.Volume24h = (double)jsonObject["data"][i]["quote"]["USD"]["volume_24h"]; if (!String.IsNullOrEmpty(jsonObject["data"][i]["quote"]["USD"]["percent_change_24h"].ToString())) { market.TrendChange24h = (double)jsonObject["data"][i]["quote"]["USD"]["percent_change_24h"]; } markets.Add(market.Name, market); } } CoinMarketCap.CheckForMarketDataRecreation(markets, systemConfiguration, log); DateTime fileDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, DateTime.UtcNow.Minute, 0).ToUniversalTime(); FileHelper.WriteTextToFile(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathCoinMarketCap + Path.DirectorySeparatorChar, "MarketData_" + fileDateTime.ToString("yyyy-MM-dd_HH.mm") + ".json", JsonConvert.SerializeObject(markets), fileDateTime, fileDateTime); log.DoLogInfo("CoinMarketCap - Market data saved."); FileHelper.CleanupFiles(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathCoinMarketCap + Path.DirectorySeparatorChar, systemConfiguration.AnalyzerSettings.MarketAnalyzer.StoreDataMaxHours); log.DoLogInfo("CoinMarketCap - Market data cleaned."); } } } catch (Exception ex) { log.DoLogCritical(ex.Message, ex); result = ex.Message; } return result; } public static void CheckForMarketDataRecreation(Dictionary markets, PTMagicConfiguration systemConfiguration, LogHelper log) { string coinMarketCapDataDirectoryPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathCoinMarketCap + Path.DirectorySeparatorChar; if (!Directory.Exists(coinMarketCapDataDirectoryPath)) { Directory.CreateDirectory(coinMarketCapDataDirectoryPath); } DirectoryInfo dataDirectory = new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathCoinMarketCap + Path.DirectorySeparatorChar); List marketFiles = dataDirectory.EnumerateFiles("MarketData*") .Select(x => { x.Refresh(); return x; }) .Where(x => x.LastWriteTimeUtc <= DateTime.UtcNow.AddHours(-24)) .ToArray().OrderByDescending(f => f.LastWriteTimeUtc).ToList(); bool build24hMarketDataFile = false; FileInfo marketFile = null; if (marketFiles.Count > 0) { marketFile = marketFiles.First(); if (marketFile.LastWriteTimeUtc <= DateTime.UtcNow.AddHours(-24).AddMinutes(-systemConfiguration.AnalyzerSettings.MarketAnalyzer.IntervalMinutes).AddSeconds(-10)) { log.DoLogDebug("CoinMarketCap - 24h market data file too old (" + marketFile.LastWriteTimeUtc.ToString() + "). Rebuilding data..."); build24hMarketDataFile = true; } } else { marketFiles = dataDirectory.EnumerateFiles("MarketData*") .Select(x => { x.Refresh(); return x; }) .Where(x => x.LastWriteTimeUtc >= DateTime.UtcNow.AddHours(-24)) .ToArray().OrderBy(f => f.LastWriteTimeUtc).ToList(); if (marketFiles.Count > 0) { marketFile = marketFiles.First(); if (marketFile.LastWriteTimeUtc >= DateTime.UtcNow.AddHours(-24).AddMinutes(systemConfiguration.AnalyzerSettings.MarketAnalyzer.IntervalMinutes).AddSeconds(10)) { log.DoLogDebug("CoinMarketCap - 24h market data file too young (" + marketFile.LastWriteTimeUtc.ToString() + "). Rebuilding data..."); build24hMarketDataFile = true; } } else { log.DoLogDebug("CoinMarketCap - 24h market data not found. Rebuilding data..."); build24hMarketDataFile = true; } } if (build24hMarketDataFile) { Dictionary markets24h = new Dictionary(); foreach (string key in markets.Keys) { Market market24h = new Market(); market24h.Position = markets.Count + 1; market24h.Name = markets[key].Name; market24h.Symbol = markets[key].Symbol; market24h.Price = markets[key].Price / (1 + (markets[key].TrendChange24h / 100)); market24h.Volume24h = markets[key].Volume24h; markets24h.Add(markets[key].Name, market24h); } DateTime fileDateTime = new DateTime(DateTime.UtcNow.ToLocalTime().AddHours(-24).Year, DateTime.UtcNow.ToLocalTime().AddHours(-24).Month, DateTime.UtcNow.ToLocalTime().AddHours(-24).Day, DateTime.UtcNow.ToLocalTime().AddHours(-24).Hour, DateTime.UtcNow.ToLocalTime().AddHours(-24).Minute, 0).ToUniversalTime(); FileHelper.WriteTextToFile(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathCoinMarketCap + Path.DirectorySeparatorChar, "MarketData_" + fileDateTime.ToString("yyyy-MM-dd_HH.mm") + ".json", JsonConvert.SerializeObject(markets24h), fileDateTime, fileDateTime); log.DoLogInfo("CoinMarketCap - 24h market data rebuilt."); } } } }