2018-05-22 10:11:50 +02:00
using System ;
using System.Collections.Generic ;
2021-06-20 12:34:37 +02:00
using System.Collections.Concurrent ;
2018-05-22 10:11:50 +02:00
using System.Linq ;
using System.IO ;
using Core.Main ;
using Core.Helper ;
using Core.Main.DataObjects.PTMagicData ;
using Newtonsoft.Json ;
using System.Net ;
2019-02-26 00:17:10 +01:00
using System.Threading.Tasks ;
2018-05-22 10:11:50 +02:00
2018-12-15 22:07:29 +01:00
namespace Core.MarketAnalyzer
{
public class Binance : BaseAnalyzer
{
public static double GetMainCurrencyPrice ( string mainMarket , PTMagicConfiguration systemConfiguration , LogHelper log )
{
2018-05-22 10:11:50 +02:00
double result = 0 ;
2018-12-15 22:07:29 +01:00
try
{
2018-05-22 10:11:50 +02:00
string baseUrl = "https://api.binance.com/api/v1/ticker/24hr?symbol=" + mainMarket + "USDT" ;
log . DoLogInfo ( "Binance - Getting main market price..." ) ;
2019-12-14 14:13:47 +01:00
Newtonsoft . Json . Linq . JObject jsonObject = GetSimpleJsonObjectFromURL ( baseUrl , log , null ) ;
2018-12-15 22:07:29 +01:00
if ( jsonObject ! = null )
{
2018-05-22 10:11:50 +02:00
log . DoLogInfo ( "Binance - Market data received for " + mainMarket + "USDT" ) ;
result = ( double ) jsonObject . GetValue ( "lastPrice" ) ;
log . DoLogInfo ( "Binance - Current price for " + mainMarket + "USDT: " + result . ToString ( "#,#0.00" ) + " USD" ) ;
}
2018-12-15 22:07:29 +01:00
}
catch ( Exception ex )
{
2018-05-22 10:11:50 +02:00
log . DoLogCritical ( ex . Message , ex ) ;
}
return result ;
}
2021-06-20 12:34:37 +02:00
public static List < string > GetMarketData ( string mainMarket , ConcurrentDictionary < string , MarketInfo > marketInfos , PTMagicConfiguration systemConfiguration , LogHelper log )
2018-12-15 22:07:29 +01:00
{
2018-05-22 10:11:50 +02:00
List < string > result = new List < string > ( ) ;
string lastMarket = "" ;
Newtonsoft . Json . Linq . JObject lastTicker = null ;
2018-12-15 22:07:29 +01:00
try
{
2018-05-22 10:11:50 +02:00
string baseUrl = "https://api.binance.com/api/v1/ticker/24hr" ;
log . DoLogInfo ( "Binance - Getting market data..." ) ;
Newtonsoft . Json . Linq . JArray jsonArray = GetSimpleJsonArrayFromURL ( baseUrl , log ) ;
2018-12-15 22:07:29 +01:00
if ( jsonArray . Count > 0 )
{
2018-05-22 10:11:50 +02:00
double mainCurrencyPrice = 1 ;
2018-12-15 22:07:29 +01:00
if ( ! mainMarket . Equals ( "USDT" , StringComparison . InvariantCultureIgnoreCase ) )
{
2018-05-22 10:11:50 +02:00
mainCurrencyPrice = Binance . GetMainCurrencyPrice ( mainMarket , systemConfiguration , log ) ;
}
log . DoLogInfo ( "Binance - Market data received for " + jsonArray . Count . ToString ( ) + " currencies" ) ;
2018-12-15 22:07:29 +01:00
if ( mainCurrencyPrice > 0 )
{
2018-05-22 10:11:50 +02:00
Dictionary < string , Market > markets = new Dictionary < string , Market > ( ) ;
2018-12-15 22:07:29 +01:00
foreach ( Newtonsoft . Json . Linq . JObject currencyTicker in jsonArray )
{
2018-05-22 10:11:50 +02:00
string marketName = currencyTicker [ "symbol" ] . ToString ( ) ;
2018-12-15 22:07:29 +01:00
//New variables for filtering out bad markets
float marketLastPrice = currencyTicker [ "lastPrice" ] . ToObject < float > ( ) ;
float marketVolume = currencyTicker [ "volume" ] . ToObject < float > ( ) ;
if ( marketName . EndsWith ( mainMarket , StringComparison . InvariantCultureIgnoreCase ) )
{
2019-03-09 09:38:46 +01:00
if ( marketLastPrice > 0 & & marketVolume > 0 )
2018-12-15 22:07:29 +01:00
{
2018-05-22 10:11:50 +02:00
2019-03-09 09:38:46 +01:00
// Set last values in case any error occurs
lastMarket = marketName ;
lastTicker = currencyTicker ;
2018-05-22 10:11:50 +02:00
2019-03-09 09:38:46 +01:00
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 ;
2018-05-22 10:11:50 +02:00
2019-03-09 09:38:46 +01:00
markets . Add ( market . Name , market ) ;
2018-05-22 10:11:50 +02:00
2019-03-09 09:38:46 +01:00
result . Add ( market . Name ) ;
2018-12-15 22:07:29 +01:00
}
else
{
//Let the user know that the problem market was ignored.
log . DoLogInfo ( "Binance - Ignoring bad market data for " + marketName ) ;
}
2018-05-22 10:11:50 +02:00
}
}
Binance . CheckFirstSeenDates ( markets , ref marketInfos , systemConfiguration , log ) ;
BaseAnalyzer . SaveMarketInfosToFile ( marketInfos , systemConfiguration , log ) ;
Binance . CheckForMarketDataRecreation ( mainMarket , markets , systemConfiguration , log ) ;
2019-03-09 09:38:46 +01:00
DateTime fileDateTime = DateTime . UtcNow ;
2018-05-22 10:11:50 +02:00
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." ) ;
2018-12-15 22:07:29 +01:00
}
else
{
2018-05-22 10:11:50 +02:00
log . DoLogError ( "Binance - Failed to get main market price for " + mainMarket + "." ) ;
result = null ;
}
}
2018-12-15 22:07:29 +01:00
}
catch ( WebException ex )
{
if ( ex . Response ! = null )
{
using ( HttpWebResponse errorResponse = ( HttpWebResponse ) ex . Response )
{
using ( StreamReader reader = new StreamReader ( errorResponse . GetResponseStream ( ) ) )
{
2018-05-22 10:11:50 +02:00
Dictionary < string , string > errorData = JsonConvert . DeserializeObject < Dictionary < string , string > > ( reader . ReadToEnd ( ) ) ;
2018-12-15 22:07:29 +01:00
if ( errorData ! = null )
{
2018-05-22 10:11:50 +02:00
string errorMessage = "Unable to get data from Binance with URL '" + errorResponse . ResponseUri + "'!" ;
2018-12-15 22:07:29 +01:00
if ( errorData . ContainsKey ( "code" ) )
{
2018-05-22 10:11:50 +02:00
errorMessage + = " - Code: " + errorData [ "code" ] ;
}
2018-12-15 22:07:29 +01:00
if ( errorData . ContainsKey ( "msg" ) )
{
2018-05-22 10:11:50 +02:00
errorMessage + = " - Message: " + errorData [ "msg" ] ;
}
log . DoLogError ( errorMessage ) ;
}
}
}
}
result = null ;
2018-12-15 22:07:29 +01:00
}
catch ( Exception ex )
{
2018-05-22 10:11:50 +02:00
log . DoLogCritical ( "Exception while getting data for '" + lastMarket + "': " + ex . Message , ex ) ;
result = null ;
}
return result ;
}
2021-06-20 12:34:37 +02:00
public static void CheckFirstSeenDates ( Dictionary < string , Market > markets , ref ConcurrentDictionary < string , MarketInfo > marketInfos , PTMagicConfiguration systemConfiguration , LogHelper log )
2018-12-15 22:07:29 +01:00
{
2018-05-22 10:11:50 +02:00
log . DoLogInfo ( "Binance - Checking first seen dates for " + markets . Count + " markets. This may take a while..." ) ;
int marketsChecked = 0 ;
2019-03-09 09:38:46 +01:00
2018-12-15 22:07:29 +01:00
foreach ( string key in markets . Keys )
{
2018-05-22 10:11:50 +02:00
// Save market info
MarketInfo marketInfo = null ;
2018-12-15 22:07:29 +01:00
if ( marketInfos . ContainsKey ( key ) )
{
2018-05-22 10:11:50 +02:00
marketInfo = marketInfos [ key ] ;
}
2018-12-15 22:07:29 +01:00
if ( marketInfo = = null )
{
2018-05-22 10:11:50 +02:00
marketInfo = new MarketInfo ( ) ;
marketInfo . Name = key ;
2021-06-20 12:34:37 +02:00
marketInfos . TryAdd ( key , marketInfo ) ;
2018-05-22 10:11:50 +02:00
marketInfo . FirstSeen = Binance . GetFirstSeenDate ( key , systemConfiguration , log ) ;
2018-12-15 22:07:29 +01:00
}
else
{
if ( marketInfo . FirstSeen = = Constants . confMinDate )
{
2018-05-22 10:11:50 +02:00
marketInfo . FirstSeen = Binance . GetFirstSeenDate ( key , systemConfiguration , log ) ;
}
}
2019-02-04 01:17:38 +01:00
marketInfo . LastSeen = DateTime . UtcNow ;
2018-05-22 10:11:50 +02:00
marketsChecked + + ;
2018-12-15 22:07:29 +01:00
if ( ( marketsChecked % 20 ) = = 0 )
{
2018-05-22 10:11:50 +02:00
log . DoLogInfo ( "Binance - Yes, I am still checking first seen dates... " + marketsChecked + "/" + markets . Count + " markets done..." ) ;
}
}
}
2018-12-15 22:07:29 +01:00
public static DateTime GetFirstSeenDate ( string marketName , PTMagicConfiguration systemConfiguration , LogHelper log )
{
2018-05-22 10:11:50 +02:00
DateTime result = Constants . confMinDate ;
string baseUrl = "https://api.binance.com/api/v1/klines?interval=1d&symbol=" + marketName + "&limit=100" ;
log . DoLogDebug ( "Binance - Getting first seen date for '" + marketName + "'..." ) ;
Newtonsoft . Json . Linq . JArray jsonArray = GetSimpleJsonArrayFromURL ( baseUrl , log ) ;
2018-12-15 22:07:29 +01:00
if ( jsonArray . Count > 0 )
{
2018-05-22 10:11:50 +02:00
result = Constants . Epoch . AddMilliseconds ( ( Int64 ) jsonArray [ 0 ] [ 0 ] ) ;
log . DoLogDebug ( "Binance - First seen date for '" + marketName + "' set to " + result . ToString ( ) ) ;
}
return result ;
}
2018-12-15 22:07:29 +01:00
public static List < MarketTick > GetMarketTicks ( string marketName , int ticksNeeded , PTMagicConfiguration systemConfiguration , LogHelper log )
{
2018-05-22 10:11:50 +02:00
List < MarketTick > result = new List < MarketTick > ( ) ;
2018-12-15 22:07:29 +01:00
try
{
2019-02-04 01:17:38 +01:00
Int64 endTime = ( Int64 ) Math . Ceiling ( DateTime . UtcNow . Subtract ( Constants . Epoch ) . TotalMilliseconds ) ;
2018-05-22 10:11:50 +02:00
int ticksLimit = 500 ;
string baseUrl = "" ;
int ticksFetched = 0 ;
2018-12-15 22:07:29 +01:00
if ( ticksNeeded < ticksLimit )
{
2018-05-22 10:11:50 +02:00
ticksLimit = ticksNeeded ;
}
bool go = true ;
2018-12-15 22:07:29 +01:00
while ( ticksFetched < ticksNeeded & & go )
{
2018-05-22 10:11:50 +02:00
baseUrl = "https://api.binance.com/api/v1/klines?interval=1m&symbol=" + marketName + "&endTime=" + endTime . ToString ( ) + "&limit=" + ticksLimit . ToString ( ) ;
log . DoLogDebug ( "Binance - Getting " + ticksLimit . ToString ( ) + " ticks for '" + marketName + "'..." ) ;
Newtonsoft . Json . Linq . JArray jsonArray = GetSimpleJsonArrayFromURL ( baseUrl , log ) ;
2018-12-15 22:07:29 +01:00
if ( jsonArray . Count > 0 )
{
2018-05-22 10:11:50 +02:00
log . DoLogDebug ( "Binance - " + jsonArray . Count . ToString ( ) + " ticks received." ) ;
2018-12-15 22:07:29 +01:00
foreach ( Newtonsoft . Json . Linq . JArray marketTick in jsonArray )
{
2018-05-22 10:11:50 +02:00
MarketTick tick = new MarketTick ( ) ;
tick . Price = ( double ) marketTick [ 4 ] ;
tick . Volume24h = ( double ) marketTick [ 7 ] ;
tick . Time = Constants . Epoch . AddMilliseconds ( ( Int64 ) marketTick [ 0 ] ) ;
result . Add ( tick ) ;
}
ticksFetched = ticksFetched + jsonArray . Count ;
endTime = endTime - ticksLimit * 60 * 1000 ;
2018-12-15 22:07:29 +01:00
if ( ticksNeeded - ticksFetched < ticksLimit )
{
2018-05-22 10:11:50 +02:00
ticksLimit = ticksNeeded - ticksFetched ;
}
2018-12-15 22:07:29 +01:00
}
else
{
2018-05-22 10:11:50 +02:00
log . DoLogDebug ( "Binance - No ticks received." ) ;
go = false ;
}
}
2018-12-15 22:07:29 +01:00
}
catch ( WebException ex )
{
if ( ex . Response ! = null )
{
using ( HttpWebResponse errorResponse = ( HttpWebResponse ) ex . Response )
{
using ( StreamReader reader = new StreamReader ( errorResponse . GetResponseStream ( ) ) )
{
2018-05-22 10:11:50 +02:00
Dictionary < string , string > errorData = JsonConvert . DeserializeObject < Dictionary < string , string > > ( reader . ReadToEnd ( ) ) ;
2018-12-15 22:07:29 +01:00
if ( errorData ! = null )
{
2018-05-22 10:11:50 +02:00
string errorMessage = "Unable to get data from Binance with URL '" + errorResponse . ResponseUri + "'!" ;
2018-12-15 22:07:29 +01:00
if ( errorData . ContainsKey ( "code" ) )
{
2018-05-22 10:11:50 +02:00
errorMessage + = " - Code: " + errorData [ "code" ] ;
}
2018-12-15 22:07:29 +01:00
if ( errorData . ContainsKey ( "msg" ) )
{
2018-05-22 10:11:50 +02:00
errorMessage + = " - Message: " + errorData [ "msg" ] ;
}
log . DoLogError ( errorMessage ) ;
}
}
}
}
result = null ;
2018-12-15 22:07:29 +01:00
}
catch ( Exception ex )
{
2018-05-22 10:11:50 +02:00
log . DoLogCritical ( ex . Message , ex ) ;
}
return result ;
}
2018-12-15 22:07:29 +01:00
public static void CheckForMarketDataRecreation ( string mainMarket , Dictionary < string , Market > markets , PTMagicConfiguration systemConfiguration , LogHelper log )
{
2018-05-22 10:11:50 +02:00
string binanceDataDirectoryPath = Directory . GetCurrentDirectory ( ) + Path . DirectorySeparatorChar + Constants . PTMagicPathData + Path . DirectorySeparatorChar + Constants . PTMagicPathExchange + Path . DirectorySeparatorChar ;
2018-12-15 22:07:29 +01:00
if ( ! Directory . Exists ( binanceDataDirectoryPath ) )
{
2018-05-22 10:11:50 +02:00
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 ;
2018-12-15 22:07:29 +01:00
if ( marketFiles . Count > 0 )
{
2018-05-22 10:11:50 +02:00
latestMarketDataFile = marketFiles . OrderByDescending ( mdf = > mdf . LastWriteTimeUtc ) . First ( ) ;
latestMarketDataFileDateTime = latestMarketDataFile . LastWriteTimeUtc ;
}
2019-02-04 01:17:38 +01:00
if ( latestMarketDataFileDateTime < DateTime . UtcNow . AddMinutes ( - 20 ) )
2018-12-15 22:07:29 +01:00
{
2019-02-04 01:17:38 +01:00
int lastMarketDataAgeInSeconds = ( int ) Math . Ceiling ( DateTime . UtcNow . Subtract ( latestMarketDataFileDateTime ) . TotalSeconds ) ;
2018-05-22 10:11:50 +02:00
// Go back in time and create market data
2019-02-04 01:17:38 +01:00
DateTime startDateTime = DateTime . UtcNow ;
DateTime endDateTime = DateTime . UtcNow . AddHours ( - systemConfiguration . AnalyzerSettings . MarketAnalyzer . StoreDataMaxHours ) ;
2018-12-15 22:07:29 +01:00
if ( latestMarketDataFileDateTime ! = Constants . confMinDate & & latestMarketDataFileDateTime > endDateTime )
{
2018-05-22 10:11:50 +02:00
// 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 ;
2018-12-15 22:07:29 +01:00
}
else
{
2018-05-22 10:11:50 +02:00
// 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 > ( ) ;
2018-12-15 22:07:29 +01:00
if ( ! mainMarket . Equals ( "USDT" , StringComparison . InvariantCultureIgnoreCase ) )
{
2018-05-22 10:11:50 +02:00
mainMarketTicks = Binance . GetMarketTicks ( mainMarket + "USDT" , totalTicks , systemConfiguration , log ) ;
}
// Get Ticks for all markets
log . DoLogDebug ( "Binance - Getting ticks for '" + markets . Count + "' markets" ) ;
2019-03-09 09:38:46 +01:00
ConcurrentDictionary < string , List < MarketTick > > marketTicks = new ConcurrentDictionary < string , List < MarketTick > > ( ) ;
2019-02-26 00:17:10 +01:00
2019-07-06 03:49:28 +02:00
int ParallelThrottle = 4 ;
2021-03-30 08:15:25 +02:00
if ( systemConfiguration . AnalyzerSettings . MarketAnalyzer . StoreDataMaxHours > 50 )
2019-07-06 03:49:28 +02:00
{
ParallelThrottle = 2 ;
log . DoLogInfo ( "----------------------------------------------------------------------------" ) ;
2021-03-30 08:15:25 +02:00
log . DoLogInfo ( "StoreDataMaxHours is greater than 50. Historical data requests will be" ) ;
log . DoLogInfo ( "throttled to avoid exceeding exchange request limits. This initial " ) ;
2019-07-06 03:49:28 +02:00
log . DoLogInfo ( "run could take more than 30 minutes. Please go outside for a walk..." ) ;
log . DoLogInfo ( "----------------------------------------------------------------------------" ) ;
}
2019-03-09 09:38:46 +01:00
Parallel . ForEach ( markets . Keys ,
2021-06-20 12:34:37 +02:00
new ParallelOptions { MaxDegreeOfParallelism = ParallelThrottle } ,
2019-02-26 00:17:10 +01:00
( key ) = >
2018-12-15 22:07:29 +01:00
{
2019-03-09 09:38:46 +01:00
if ( ! marketTicks . TryAdd ( key , GetMarketTicks ( key , totalTicks , systemConfiguration , log ) ) )
{
// Failed to add ticks to dictionary
throw new Exception ( "Failed to add ticks for " + key + " to the memory dictionary, results may be incorrectly calculated!" ) ;
}
2018-05-22 10:11:50 +02:00
2018-12-15 22:07:29 +01:00
if ( ( marketTicks . Count % 10 ) = = 0 )
{
2018-05-22 10:11:50 +02:00
log . DoLogInfo ( "Binance - No worries, I am still alive... " + marketTicks . Count + "/" + markets . Count + " markets done..." ) ;
}
2019-02-26 00:17:10 +01:00
} ) ;
2018-05-22 10:11:50 +02:00
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 ;
2018-12-15 22:07:29 +01:00
if ( marketTicks . Count > 0 )
{
for ( DateTime tickTime = startDateTime ; tickTime > = endDateTime ; tickTime = tickTime . AddMinutes ( - 1 ) )
{
2018-05-22 10:11:50 +02:00
completedTicks + + ;
double mainCurrencyPrice = 1 ;
2018-12-15 22:07:29 +01:00
if ( mainMarketTicks . Count > 0 )
{
2018-05-22 10:11:50 +02:00
List < MarketTick > mainCurrencyTickRange = mainMarketTicks . FindAll ( t = > t . Time < = tickTime ) ;
2018-12-15 22:07:29 +01:00
if ( mainCurrencyTickRange . Count > 0 )
{
2018-05-22 10:11:50 +02:00
MarketTick mainCurrencyTick = mainCurrencyTickRange . OrderByDescending ( t = > t . Time ) . First ( ) ;
mainCurrencyPrice = mainCurrencyTick . Price ;
}
}
2021-06-20 12:34:37 +02:00
ConcurrentDictionary < string , Market > tickMarkets = new ConcurrentDictionary < string , Market > ( ) ;
2018-05-22 10:11:50 +02:00
2021-06-20 12:34:37 +02:00
Parallel . ForEach ( markets . Keys ,
( key ) = >
{
List < MarketTick > tickRange = marketTicks [ key ] ! = null ? marketTicks [ key ] . FindAll ( t = > t . Time < = tickTime ) : new List < MarketTick > ( ) ;
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 . TryAdd ( market . Name , market ) ;
}
} ) ;
2018-05-22 10:11:50 +02:00
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." ) ;
2018-12-15 22:07:29 +01:00
if ( ( completedTicks % 100 ) = = 0 )
{
2018-05-22 10:11:50 +02:00
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!" ) ;
}
}
}
2019-03-09 09:38:46 +01:00
}