public static void CheckFirstSeenDates(Dictionary <string, Market> markets, ref Dictionary <string, MarketInfo> marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { log.DoLogInfo("Binance - Checking first seen dates for " + markets.Count + " markets. This may take a while..."); int marketsChecked = 0; foreach (string key in markets.Keys) { // Save market info MarketInfo marketInfo = null; if (marketInfos.ContainsKey(key)) { marketInfo = marketInfos[key]; } if (marketInfo == null) { marketInfo = new MarketInfo(); marketInfo.Name = key; marketInfos.Add(key, marketInfo); marketInfo.FirstSeen = Binance.GetFirstSeenDate(key, systemConfiguration, log); } else { if (marketInfo.FirstSeen == Constants.confMinDate) { marketInfo.FirstSeen = Binance.GetFirstSeenDate(key, systemConfiguration, log); } } marketInfo.LastSeen = DateTime.Now.ToUniversalTime(); marketsChecked++; if ((marketsChecked % 20) == 0) { log.DoLogInfo("Binance - Yes, I am still checking first seen dates... " + marketsChecked + "/" + markets.Count + " markets done..."); } } }
public static List <string> GetMarketData(string mainMarket, Dictionary <string, MarketInfo> marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { List <string> result = new List <string>(); string lastMarket = ""; Newtonsoft.Json.Linq.JObject lastTicker = null; try { string baseUrl = "https://api.binance.com/api/v1/ticker/24hr"; log.DoLogInfo("Binance - Getting market data..."); Newtonsoft.Json.Linq.JArray jsonArray = GetSimpleJsonArrayFromURL(baseUrl, log); if (jsonArray.Count > 0) { double mainCurrencyPrice = 1; if (!mainMarket.Equals("USDT", StringComparison.InvariantCultureIgnoreCase)) { mainCurrencyPrice = Binance.GetMainCurrencyPrice(mainMarket, systemConfiguration, log); } log.DoLogInfo("Binance - Market data received for " + jsonArray.Count.ToString() + " currencies"); if (mainCurrencyPrice > 0) { Dictionary <string, Market> markets = new Dictionary <string, Market>(); foreach (Newtonsoft.Json.Linq.JObject currencyTicker in jsonArray) { string marketName = currencyTicker["symbol"].ToString(); if (marketName.EndsWith(mainMarket, StringComparison.InvariantCultureIgnoreCase)) { // Set last values in case any error occurs lastMarket = marketName; lastTicker = currencyTicker; Market market = new Market(); market.Position = markets.Count + 1; market.Name = marketName; market.Symbol = currencyTicker["symbol"].ToString(); market.Price = SystemHelper.TextToDouble(currencyTicker["lastPrice"].ToString(), 0, "en-US"); market.Volume24h = SystemHelper.TextToDouble(currencyTicker["quoteVolume"].ToString(), 0, "en-US"); market.MainCurrencyPriceUSD = mainCurrencyPrice; markets.Add(market.Name, market); result.Add(market.Name); } } Binance.CheckFirstSeenDates(markets, ref marketInfos, systemConfiguration, log); BaseAnalyzer.SaveMarketInfosToFile(marketInfos, systemConfiguration, log); Binance.CheckForMarketDataRecreation(mainMarket, markets, systemConfiguration, log); DateTime fileDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, 0).ToUniversalTime(); FileHelper.WriteTextToFile(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathExchange + Path.DirectorySeparatorChar, "MarketData_" + fileDateTime.ToString("yyyy-MM-dd_HH.mm") + ".json", JsonConvert.SerializeObject(markets), fileDateTime, fileDateTime); log.DoLogInfo("Binance - Market data saved for " + markets.Count.ToString() + " markets with " + mainMarket + "."); FileHelper.CleanupFiles(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathExchange + Path.DirectorySeparatorChar, systemConfiguration.AnalyzerSettings.MarketAnalyzer.StoreDataMaxHours); log.DoLogInfo("Binance - Market data cleaned."); } else { log.DoLogError("Binance - Failed to get main market price for " + mainMarket + "."); result = null; } } } catch (WebException ex) { if (ex.Response != null) { using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response) { using (StreamReader reader = new StreamReader(errorResponse.GetResponseStream())) { Dictionary <string, string> errorData = JsonConvert.DeserializeObject <Dictionary <string, string> >(reader.ReadToEnd()); if (errorData != null) { string errorMessage = "Unable to get data from Binance with URL '" + errorResponse.ResponseUri + "'!"; if (errorData.ContainsKey("code")) { errorMessage += " - Code: " + errorData["code"]; } if (errorData.ContainsKey("msg")) { errorMessage += " - Message: " + errorData["msg"]; } log.DoLogError(errorMessage); } } } } result = null; } catch (Exception ex) { log.DoLogCritical("Exception while getting data for '" + lastMarket + "': " + ex.Message, ex); result = null; } return(result); }
public static void CheckForMarketDataRecreation(string mainMarket, Dictionary <string, Market> markets, PTMagicConfiguration systemConfiguration, LogHelper log) { string binanceDataDirectoryPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathExchange + Path.DirectorySeparatorChar; if (!Directory.Exists(binanceDataDirectoryPath)) { Directory.CreateDirectory(binanceDataDirectoryPath); } DirectoryInfo dataDirectory = new DirectoryInfo(binanceDataDirectoryPath); // Check for existing market files DateTime latestMarketDataFileDateTime = Constants.confMinDate; List <FileInfo> marketFiles = dataDirectory.EnumerateFiles("MarketData*").ToList(); FileInfo latestMarketDataFile = null; if (marketFiles.Count > 0) { latestMarketDataFile = marketFiles.OrderByDescending(mdf => mdf.LastWriteTimeUtc).First(); latestMarketDataFileDateTime = latestMarketDataFile.LastWriteTimeUtc; } if (latestMarketDataFileDateTime < DateTime.Now.ToUniversalTime().AddMinutes(-20)) { int lastMarketDataAgeInSeconds = (int)Math.Ceiling(DateTime.Now.ToUniversalTime().Subtract(latestMarketDataFileDateTime).TotalSeconds); // Go back in time and create market data DateTime startDateTime = DateTime.Now.ToUniversalTime(); DateTime endDateTime = DateTime.Now.ToUniversalTime().AddHours(-systemConfiguration.AnalyzerSettings.MarketAnalyzer.StoreDataMaxHours); if (latestMarketDataFileDateTime != Constants.confMinDate && latestMarketDataFileDateTime > endDateTime) { // Existing market files too old => Recreate market data for configured timeframe log.DoLogInfo("Binance - Recreating market data for " + markets.Count + " markets over " + SystemHelper.GetProperDurationTime(lastMarketDataAgeInSeconds) + ". This may take a while..."); endDateTime = latestMarketDataFileDateTime; } else { // No existing market files found => Recreate market data for configured timeframe log.DoLogInfo("Binance - Recreating market data for " + markets.Count + " markets over " + systemConfiguration.AnalyzerSettings.MarketAnalyzer.StoreDataMaxHours + " hours. This may take a while..."); } int totalTicks = (int)Math.Ceiling(startDateTime.Subtract(endDateTime).TotalMinutes); // Get Ticks for main market List <MarketTick> mainMarketTicks = new List <MarketTick>(); if (!mainMarket.Equals("USDT", StringComparison.InvariantCultureIgnoreCase)) { mainMarketTicks = Binance.GetMarketTicks(mainMarket + "USDT", totalTicks, systemConfiguration, log); } // Get Ticks for all markets log.DoLogDebug("Binance - Getting ticks for '" + markets.Count + "' markets"); Dictionary <string, List <MarketTick> > marketTicks = new Dictionary <string, List <MarketTick> >(); foreach (string key in markets.Keys) { marketTicks.Add(key, Binance.GetMarketTicks(key, totalTicks, systemConfiguration, log)); if ((marketTicks.Count % 10) == 0) { log.DoLogInfo("Binance - No worries, I am still alive... " + marketTicks.Count + "/" + markets.Count + " markets done..."); } } log.DoLogInfo("Binance - Ticks completed."); log.DoLogInfo("Binance - Creating initial market data ticks. This may take another while..."); // Go back in time and create market data int completedTicks = 0; if (marketTicks.Count > 0) { for (DateTime tickTime = startDateTime; tickTime >= endDateTime; tickTime = tickTime.AddMinutes(-1)) { completedTicks++; double mainCurrencyPrice = 1; if (mainMarketTicks.Count > 0) { List <MarketTick> mainCurrencyTickRange = mainMarketTicks.FindAll(t => t.Time <= tickTime); if (mainCurrencyTickRange.Count > 0) { MarketTick mainCurrencyTick = mainCurrencyTickRange.OrderByDescending(t => t.Time).First(); mainCurrencyPrice = mainCurrencyTick.Price; } } Dictionary <string, Market> tickMarkets = new Dictionary <string, Market>(); foreach (string key in markets.Keys) { List <MarketTick> tickRange = marketTicks[key].FindAll(t => t.Time <= tickTime); if (tickRange.Count > 0) { MarketTick marketTick = tickRange.OrderByDescending(t => t.Time).First(); Market market = new Market(); market.Position = markets.Count + 1; market.Name = key; market.Symbol = key; market.Price = marketTick.Price; //market.Volume24h = marketTick.Volume24h; market.MainCurrencyPriceUSD = mainCurrencyPrice; tickMarkets.Add(market.Name, market); } } DateTime fileDateTime = new DateTime(tickTime.ToLocalTime().Year, tickTime.ToLocalTime().Month, tickTime.ToLocalTime().Day, tickTime.ToLocalTime().Hour, tickTime.ToLocalTime().Minute, 0).ToUniversalTime(); FileHelper.WriteTextToFile(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathExchange + Path.DirectorySeparatorChar, "MarketData_" + fileDateTime.ToString("yyyy-MM-dd_HH.mm") + ".json", JsonConvert.SerializeObject(tickMarkets), fileDateTime, fileDateTime); log.DoLogDebug("Binance - Market data saved for tick " + fileDateTime.ToString() + " - MainCurrencyPrice=" + mainCurrencyPrice.ToString("#,#0.00") + " USD."); if ((completedTicks % 100) == 0) { log.DoLogInfo("Binance - Our magicbots are still at work, hang on... " + completedTicks + "/" + totalTicks + " ticks done..."); } } } log.DoLogInfo("Binance - Initial market data created. Ready to go!"); } }