diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index 0083de6..25865a1 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -36,8 +36,10 @@ namespace Core.Main.DataObjects.PTMagicData public bool TestMode { get; set; } = true; public bool EnableBetaFeatures { get; set; } = false; public string ProfitTrailerLicense { get; set; } = ""; + public string ProfitTrailerLicenseXtra { get; set; } = ""; public string ProfitTrailerServerAPIToken { get; set; } - public string ProfitTrailerMonitorURL { get; set; } = "http://localhost:8081/"; + public string ProfitTrailerMonitorURL { get; set; } = ""; + public string ProfitTrailerMonitorURLXtra { get; set; } = ""; public string ProfitTrailerDefaultSettingName { get; set; } = "default"; public int FloodProtectionMinutes { get; set; } = 15; public string Exchange { get; set; } @@ -517,4 +519,4 @@ namespace Core.Main.DataObjects.PTMagicData } #endregion -} +} \ No newline at end of file diff --git a/Core/DataObjects/ProfitTrailerData.cs b/Core/DataObjects/ProfitTrailerData.cs index 6cc70b1..df01a9a 100644 --- a/Core/DataObjects/ProfitTrailerData.cs +++ b/Core/DataObjects/ProfitTrailerData.cs @@ -108,7 +108,28 @@ namespace Core.Main.DataObjects if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh)) { _sellLog.Clear(); - this.BuildSellLogData(GetDataFromProfitTrailer("/api/v2/data/sales")); + + // Page through the sales data summarizing it. + bool exitLoop = false; + int pageIndex = 1; + + while (!exitLoop) + { + var sellDataPage = GetDataFromProfitTrailer("/api/v2/data/sales?perPage=5000&sort=SOLDDATE&sortDirection=ASCENDING&page=" + pageIndex); + if (sellDataPage != null && sellDataPage.data.Count > 0) + { + // Add sales data page to collection + this.BuildSellLogData(sellDataPage); + pageIndex++; + } + else + { + // All data retrieved + exitLoop = true; + } + } + + // Update sell log refresh time _sellLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); } } @@ -265,7 +286,10 @@ namespace Core.Main.DataObjects private dynamic GetDataFromProfitTrailer(string callPath, bool arrayReturned = false) { string rawBody = ""; - string url = string.Format("{0}{1}?token={2}", _systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL, callPath, _systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken); + string url = string.Format("{0}{1}{2}token={3}", _systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL, + callPath, + callPath.Contains("?") ? "&" : "?", + _systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken); // Get the data from PT Debug.WriteLine(String.Format("{0} - Calling '{1}'", DateTime.UtcNow, url)); @@ -331,15 +355,9 @@ namespace Core.Main.DataObjects sellLogData.ProfitPercent = rsld.profit; sellLogData.SoldPrice = rsld.currentPrice; sellLogData.AverageBuyPrice = rsld.avgPrice; - sellLogData.TotalCost = sellLogData.SoldAmount * sellLogData.AverageBuyPrice; + sellLogData.TotalCost = rsld.totalCost; + sellLogData.Profit = rsld.profitCurrency; - // check if bot is a shortbot via PT API. Losses on short bot currently showing as gains. Issue #195 - // code removed - - double soldValueRaw = (sellLogData.SoldAmount * sellLogData.SoldPrice); - double soldValueAfterFees = soldValueRaw - (soldValueRaw * ((double)rsld.fee / 100)); - sellLogData.SoldValue = soldValueAfterFees; - sellLogData.Profit = Math.Round(sellLogData.SoldValue - sellLogData.TotalCost, 8); //Convert Unix Timestamp to Datetime System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc); diff --git a/Core/Helper/TelegramHelper.cs b/Core/Helper/TelegramHelper.cs index 16754ac..cd7d391 100644 --- a/Core/Helper/TelegramHelper.cs +++ b/Core/Helper/TelegramHelper.cs @@ -8,19 +8,15 @@ namespace Core.Helper { public static class TelegramHelper { - public static void SendMessage(string botToken, Int64 chatId, string message, bool useSilentMode, LogHelper log) + public async static void SendMessage(string botToken, Int64 chatId, string message, bool useSilentMode, LogHelper log) { if (!botToken.Equals("") && chatId != 0) { try { TelegramBotClient botClient = new TelegramBotClient(botToken); - System.Threading.Tasks.Task sentMessage = botClient.SendTextMessageAsync(chatId, message, ParseMode.Markdown, false, useSilentMode); - - if (sentMessage.IsCompleted) - { - log.DoLogDebug("Telegram message sent to ChatId " + chatId.ToString() + " on Bot Token '" + botToken + "'"); - } + await botClient.SendTextMessageAsync(chatId: chatId, text: message, parseMode: ParseMode.Markdown,disableNotification: useSilentMode); + log.DoLogDebug("Telegram message sent to ChatId " + chatId.ToString() + " on Bot Token '" + botToken + "'"); } catch (Exception ex) { diff --git a/Core/Main/PTMagic.cs b/Core/Main/PTMagic.cs index 9600417..82460d6 100644 --- a/Core/Main/PTMagic.cs +++ b/Core/Main/PTMagic.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Threading; using System.IO; using System.Linq; @@ -52,7 +53,7 @@ namespace Core.Main private List _indicatorsLines = null; private List _exchangeMarketList = null; private List _marketList = new List(); - private Dictionary _marketInfos = new Dictionary(); + private ConcurrentDictionary _marketInfos = new ConcurrentDictionary(); private Dictionary _averageMarketTrendChanges = new Dictionary(); private Dictionary> _singleMarketTrendChanges = new Dictionary>(); private Dictionary> _globalMarketTrendChanges = new Dictionary>(); @@ -432,7 +433,7 @@ namespace Core.Main } } - public Dictionary MarketInfos + public ConcurrentDictionary MarketInfos { get { @@ -701,13 +702,13 @@ namespace Core.Main // Check if the program is enabled if (this.PTMagicConfiguration.GeneralSettings.Application.IsEnabled) { + result = RunProfitTrailerSettingsAPIChecks(); try { if (this.PTMagicConfiguration.GeneralSettings.Application.TestMode) { - this.Log.DoLogInfo("TESTMODE ENABLED - No files will be changed!"); + this.Log.DoLogWarn("TESTMODE ENABLED - No PT settings will be changed!"); } - result = RunProfitTrailerSettingsAPIChecks(); // Check for CoinMarketCap API Key if (!String.IsNullOrEmpty(this.PTMagicConfiguration.GeneralSettings.Application.CoinMarketCapAPIKey)) @@ -731,7 +732,7 @@ namespace Core.Main } catch (System.NullReferenceException) { - this.Log.DoLogError("PTM failed to read the Config File. That means something in the File is either missing or incorrect. If this happend after an update please take a look at the release notes at: https://github.com/PTMagicians/PTMagic/releases"); + this.Log.DoLogError("PTM failed to read the General Settings file. That means something in the file is either missing or incorrect. If this happend after an update please take a look at the release notes at: https://github.com/PTMagicians/PTMagic/releases"); Console.WriteLine("Press enter to close the Application..."); Console.ReadLine(); Environment.Exit(0); @@ -739,7 +740,7 @@ namespace Core.Main } else { - this.Log.DoLogWarn("PTMagic disabled, shutting down..."); + this.Log.DoLogWarn("PTMagic is disabled. The scheduled raid was skipped."); result = false; } @@ -952,7 +953,7 @@ namespace Core.Main this.Log.DoLogInfo("+ Active setting: " + this.LastRuntimeSummary.CurrentGlobalSetting.SettingName); this.Log.DoLogInfo("+ Global setting changed: " + ((this.LastRuntimeSummary.LastGlobalSettingSwitch == this.LastRuntimeSummary.LastRuntime) ? "Yes" : "No") + " " + ((this.LastRuntimeSummary.FloodProtectedSetting != null) ? "(Flood protection!)" : "")); this.Log.DoLogInfo("+ Single Market Settings changed: " + (this.SingleMarketSettingChanged ? "Yes" : "No")); - this.Log.DoLogInfo("+ PT Config updated: " + (((this.GlobalSettingWritten || this.SingleMarketSettingChanged) && !this.PTMagicConfiguration.GeneralSettings.Application.TestMode) ? "Yes" : "No")); + this.Log.DoLogInfo("+ PT Config updated: " + (((this.GlobalSettingWritten || this.SingleMarketSettingChanged) && !this.PTMagicConfiguration.GeneralSettings.Application.TestMode) ? "Yes" : "No") + ((this.PTMagicConfiguration.GeneralSettings.Application.TestMode) ? " - TESTMODE active" : "")); this.Log.DoLogInfo("+ Markets with active single market settings: " + this.TriggeredSingleMarketSettings.Count.ToString()); foreach (string activeSMS in this.SingleMarketSettingsCount.Keys) { @@ -969,7 +970,7 @@ namespace Core.Main else { this.State = Constants.PTMagicBotState_Idle; - Log.DoLogWarn("PTMagic disabled, shutting down until next raid..."); + Log.DoLogWarn("PTMagic is disabled. The scheduled raid was skipped."); } } catch (Exception ex) @@ -1538,7 +1539,7 @@ namespace Core.Main market = market.Replace("-", ""); break; case "poloniex": - market = market.Replace("-", ""); + market = market.Replace("_", ""); break; } bool stopTriggers = false; @@ -2194,9 +2195,12 @@ namespace Core.Main if (!this.PTMagicConfiguration.GeneralSettings.Application.TestMode) { SettingsAPI.SendPropertyLinesToAPI(this.PairsLines, this.DCALines, this.IndicatorsLines, this.PTMagicConfiguration, this.Log); + this.Log.DoLogInfo("Settings updates sent to PT!"); + } + else + { + this.Log.DoLogWarn("TESTMODE enabled -- no updates sent to PT!"); } - - this.Log.DoLogInfo("Properties saved!"); } else { diff --git a/Core/MarketAnalyzer/BaseAnalyzer.cs b/Core/MarketAnalyzer/BaseAnalyzer.cs index 4f0ff6d..120faab 100644 --- a/Core/MarketAnalyzer/BaseAnalyzer.cs +++ b/Core/MarketAnalyzer/BaseAnalyzer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Net; @@ -153,16 +154,16 @@ namespace Core.MarketAnalyzer return result; } - public static Dictionary GetMarketInfosFromFile(PTMagicConfiguration systemConfiguration, LogHelper log) + public static ConcurrentDictionary GetMarketInfosFromFile(PTMagicConfiguration systemConfiguration, LogHelper log) { - Dictionary result = new Dictionary(); + ConcurrentDictionary result = new ConcurrentDictionary(); string marketInfoFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathExchange + Path.DirectorySeparatorChar + "MarketInfo.json"; if (File.Exists(marketInfoFilePath)) { try { - result = JsonConvert.DeserializeObject>(System.IO.File.ReadAllText(marketInfoFilePath)); + result = JsonConvert.DeserializeObject>(System.IO.File.ReadAllText(marketInfoFilePath)); } catch (Exception ex) { @@ -171,12 +172,12 @@ namespace Core.MarketAnalyzer } if (result == null) { - result = new Dictionary(); + result = new ConcurrentDictionary(); } return result; } - public static void SaveMarketInfosToFile(Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static void SaveMarketInfosToFile(ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { FileHelper.WriteTextToFile(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + Constants.PTMagicPathExchange + Path.DirectorySeparatorChar, "MarketInfo.json", JsonConvert.SerializeObject(marketInfos)); } @@ -316,7 +317,7 @@ namespace Core.MarketAnalyzer market = market.Replace("-", ""); break; case "poloniex": - market = market.Replace("-", ""); + market = market.Replace("_", ""); break; } if (recentMarkets.TryGetValue(recentMarketPair.Key, out recentMarket)) diff --git a/Core/MarketAnalyzer/Binance.cs b/Core/MarketAnalyzer/Binance.cs index b2e6c68..3d28203 100644 --- a/Core/MarketAnalyzer/Binance.cs +++ b/Core/MarketAnalyzer/Binance.cs @@ -1,17 +1,14 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Linq; using System.IO; -using System.Text; using Core.Main; using Core.Helper; using Core.Main.DataObjects.PTMagicData; using Newtonsoft.Json; -using Core.ProfitTrailer; using System.Net; -using System.Threading; using System.Threading.Tasks; -using System.Collections.Concurrent; namespace Core.MarketAnalyzer { @@ -43,7 +40,7 @@ namespace Core.MarketAnalyzer return result; } - public static List GetMarketData(string mainMarket, Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static List GetMarketData(string mainMarket, ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { List result = new List(); @@ -163,7 +160,7 @@ namespace Core.MarketAnalyzer return result; } - public static void CheckFirstSeenDates(Dictionary markets, ref Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static void CheckFirstSeenDates(Dictionary markets, ref ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { log.DoLogInfo("Binance - Checking first seen dates for " + markets.Count + " markets. This may take a while..."); @@ -182,7 +179,7 @@ namespace Core.MarketAnalyzer { marketInfo = new MarketInfo(); marketInfo.Name = key; - marketInfos.Add(key, marketInfo); + marketInfos.TryAdd(key, marketInfo); marketInfo.FirstSeen = Binance.GetFirstSeenDate(key, systemConfiguration, log); } else @@ -375,7 +372,7 @@ namespace Core.MarketAnalyzer } Parallel.ForEach(markets.Keys, - new ParallelOptions { MaxDegreeOfParallelism = ParallelThrottle}, + new ParallelOptions { MaxDegreeOfParallelism = ParallelThrottle }, (key) => { if (!marketTicks.TryAdd(key, GetMarketTicks(key, totalTicks, systemConfiguration, log))) @@ -413,26 +410,28 @@ namespace Core.MarketAnalyzer } } - Dictionary tickMarkets = new Dictionary(); - foreach (string key in markets.Keys) - { - List tickRange = marketTicks[key] != null ? marketTicks[key].FindAll(t => t.Time <= tickTime) : new List(); + ConcurrentDictionary tickMarkets = new ConcurrentDictionary(); - if (tickRange.Count > 0) - { - MarketTick marketTick = tickRange.OrderByDescending(t => t.Time).First(); + Parallel.ForEach(markets.Keys, + (key) => + { + List tickRange = marketTicks[key] != null ? marketTicks[key].FindAll(t => t.Time <= tickTime) : new List(); - 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; + if (tickRange.Count > 0) + { + MarketTick marketTick = tickRange.OrderByDescending(t => t.Time).First(); - tickMarkets.Add(market.Name, market); - } - } + 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); + } + }); DateTime fileDateTime = new DateTime(tickTime.ToLocalTime().Year, tickTime.ToLocalTime().Month, tickTime.ToLocalTime().Day, tickTime.ToLocalTime().Hour, tickTime.ToLocalTime().Minute, 0).ToUniversalTime(); diff --git a/Core/MarketAnalyzer/BinanceFutures.cs b/Core/MarketAnalyzer/BinanceFutures.cs index 52b99e2..1552a66 100644 --- a/Core/MarketAnalyzer/BinanceFutures.cs +++ b/Core/MarketAnalyzer/BinanceFutures.cs @@ -1,17 +1,14 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Linq; using System.IO; -using System.Text; using Core.Main; using Core.Helper; using Core.Main.DataObjects.PTMagicData; using Newtonsoft.Json; -using Core.ProfitTrailer; using System.Net; -using System.Threading; using System.Threading.Tasks; -using System.Collections.Concurrent; namespace Core.MarketAnalyzer { @@ -43,7 +40,7 @@ namespace Core.MarketAnalyzer return result; } - public static List GetMarketData(string mainMarket, Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static List GetMarketData(string mainMarket, ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { List result = new List(); @@ -160,7 +157,7 @@ namespace Core.MarketAnalyzer return result; } - public static void CheckFirstSeenDates(Dictionary markets, ref Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static void CheckFirstSeenDates(Dictionary markets, ref ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { log.DoLogInfo("BinanceFutures - Checking first seen dates for " + markets.Count + " markets. This may take a while..."); @@ -179,7 +176,7 @@ namespace Core.MarketAnalyzer { marketInfo = new MarketInfo(); marketInfo.Name = key; - marketInfos.Add(key, marketInfo); + marketInfos.TryAdd(key, marketInfo); marketInfo.FirstSeen = BinanceFutures.GetFirstSeenDate(key, systemConfiguration, log); } else diff --git a/Core/MarketAnalyzer/BinanceUS.cs b/Core/MarketAnalyzer/BinanceUS.cs index 63b1318..0b09180 100644 --- a/Core/MarketAnalyzer/BinanceUS.cs +++ b/Core/MarketAnalyzer/BinanceUS.cs @@ -2,14 +2,11 @@ using System.Collections.Generic; using System.Linq; using System.IO; -using System.Text; using Core.Main; using Core.Helper; using Core.Main.DataObjects.PTMagicData; using Newtonsoft.Json; -using Core.ProfitTrailer; using System.Net; -using System.Threading; using System.Threading.Tasks; using System.Collections.Concurrent; @@ -48,7 +45,7 @@ namespace Core.MarketAnalyzer } } - public static List GetMarketData(string mainMarket, Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static List GetMarketData(string mainMarket, ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { List result = new List(); @@ -168,7 +165,7 @@ namespace Core.MarketAnalyzer return result; } - public static void CheckFirstSeenDates(Dictionary markets, ref Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static void CheckFirstSeenDates(Dictionary markets, ref ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { log.DoLogInfo("BinanceUS - Checking first seen dates for " + markets.Count + " markets. This may take a while..."); @@ -187,7 +184,7 @@ namespace Core.MarketAnalyzer { marketInfo = new MarketInfo(); marketInfo.Name = key; - marketInfos.Add(key, marketInfo); + marketInfos.TryAdd(key, marketInfo); marketInfo.FirstSeen = BinanceUS.GetFirstSeenDate(key, systemConfiguration, log); } else diff --git a/Core/MarketAnalyzer/Bittrex.cs b/Core/MarketAnalyzer/Bittrex.cs index c7ede44..e5470e1 100644 --- a/Core/MarketAnalyzer/Bittrex.cs +++ b/Core/MarketAnalyzer/Bittrex.cs @@ -1,14 +1,12 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Linq; using System.IO; -using System.Text; using Core.Main; using Core.Helper; using Core.Main.DataObjects.PTMagicData; using Newtonsoft.Json; -using Core.ProfitTrailer; -using System.Threading; using System.Threading.Tasks; namespace Core.MarketAnalyzer @@ -44,7 +42,7 @@ namespace Core.MarketAnalyzer return result; } - public static List GetMarketData(string mainMarket, Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static List GetMarketData(string mainMarket, ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { List result = new List(); @@ -104,7 +102,7 @@ namespace Core.MarketAnalyzer { marketInfo = new MarketInfo(); marketInfo.Name = marketName; - marketInfos.Add(marketName, marketInfo); + marketInfos.TryAdd(marketName, marketInfo); } if (currencyTicker["Summary"]["Created"].Type == Newtonsoft.Json.Linq.JTokenType.Date) marketInfo.FirstSeen = (DateTime)currencyTicker["Summary"]["Created"]; marketInfo.LastSeen = DateTime.UtcNow; diff --git a/Core/MarketAnalyzer/Poloniex.cs b/Core/MarketAnalyzer/Poloniex.cs index 84a5848..64f29aa 100644 --- a/Core/MarketAnalyzer/Poloniex.cs +++ b/Core/MarketAnalyzer/Poloniex.cs @@ -1,14 +1,12 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Linq; using System.IO; -using System.Text; using Core.Main; using Core.Helper; using Core.Main.DataObjects.PTMagicData; using Newtonsoft.Json; -using Core.ProfitTrailer; -using System.Threading; using System.Threading.Tasks; namespace Core.MarketAnalyzer @@ -44,7 +42,7 @@ namespace Core.MarketAnalyzer return result; } - public static List GetMarketData(string mainMarket, Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static List GetMarketData(string mainMarket, ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { List result = new List(); @@ -125,7 +123,7 @@ namespace Core.MarketAnalyzer return result; } - public static void CheckFirstSeenDates(Dictionary markets, ref Dictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) + public static void CheckFirstSeenDates(Dictionary markets, ref ConcurrentDictionary marketInfos, PTMagicConfiguration systemConfiguration, LogHelper log) { log.DoLogInfo("Poloniex - Checking first seen dates for " + markets.Count + " markets. This may take a while..."); @@ -142,7 +140,7 @@ namespace Core.MarketAnalyzer { marketInfo = new MarketInfo(); marketInfo.Name = key; - marketInfos.Add(key, marketInfo); + marketInfos.TryAdd(key, marketInfo); marketInfo.FirstSeen = Poloniex.GetFirstSeenDate(key, systemConfiguration, log); } else diff --git a/Core/ProfitTrailer/SettingsAPI.cs b/Core/ProfitTrailer/SettingsAPI.cs index 83dd315..ef77c4d 100644 --- a/Core/ProfitTrailer/SettingsAPI.cs +++ b/Core/ProfitTrailer/SettingsAPI.cs @@ -19,95 +19,122 @@ namespace Core.ProfitTrailer bool transferCompleted = false; bool transferCanceled = false; - while (!transferCompleted && !transferCanceled) + // get PT license list + string licenses = systemConfiguration.GeneralSettings.Application.ProfitTrailerLicense; + if (systemConfiguration.GeneralSettings.Application.ProfitTrailerLicenseXtra != "") { - try + licenses = licenses + ", " + systemConfiguration.GeneralSettings.Application.ProfitTrailerLicenseXtra; + } + List licenseList = SystemHelper.ConvertTokenStringToList(licenses, ","); + int licenseCount = licenseList.Count; + + // get URL list + string urls = systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL; + if (systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURLXtra != "") + { + urls = urls + ", " + systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURLXtra; + } + List urlList = SystemHelper.ConvertTokenStringToList(urls, ","); + int urlCount = urlList.Count; + + log.DoLogInfo("Found " + licenseCount + " licenses and " + urlCount + " URLs"); + if (urlCount != licenseCount) + { + log.DoLogWarn("ERROR - urlCount must match licenseCount"); + } + for (int i = 0; i < licenseCount; i++) + { + transferCompleted = false; + while (!transferCompleted && !transferCanceled) { - ServicePointManager.Expect100Continue = true; - ServicePointManager.DefaultConnectionLimit = 9999; - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; - ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(CertificateHelper.AllwaysGoodCertificate); - - HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL + "settingsapi/settings/saveAll"); - httpWebRequest.ContentType = "application/x-www-form-urlencoded"; - httpWebRequest.Method = "POST"; - httpWebRequest.Proxy = null; - httpWebRequest.Timeout = 30000; - - // PT is using ordinary POST data, not JSON - string query = "configName=" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "&license=" + systemConfiguration.GeneralSettings.Application.ProfitTrailerLicense; - string pairsPropertiesString = SystemHelper.ConvertListToTokenString(pairsLines, Environment.NewLine, false); - string dcaPropertiesString = SystemHelper.ConvertListToTokenString(dcaLines, Environment.NewLine, false); - string indicatorsPropertiesString = SystemHelper.ConvertListToTokenString(indicatorsLines, Environment.NewLine, false); - query += "&pairsData=" + WebUtility.UrlEncode(pairsPropertiesString) + "&dcaData=" + WebUtility.UrlEncode(dcaPropertiesString) + "&indicatorsData=" + WebUtility.UrlEncode(indicatorsPropertiesString); - - byte[] formData = Encoding.ASCII.GetBytes(query); - httpWebRequest.ContentLength = formData.Length; - - using (Stream stream = httpWebRequest.GetRequestStream()) + try { - stream.Write(formData, 0, formData.Length); + ServicePointManager.Expect100Continue = true; + ServicePointManager.DefaultConnectionLimit = 9999; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; + ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(CertificateHelper.AllwaysGoodCertificate); + HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(urlList[i] + "settingsapi/settings/saveAll"); + httpWebRequest.ContentType = "application/x-www-form-urlencoded"; + httpWebRequest.Method = "POST"; + httpWebRequest.Proxy = null; + httpWebRequest.Timeout = 30000; + + // PT is using ordinary POST data, not JSON + string query = "configName=" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName; + query = query + "&license=" + licenseList[i]; + string pairsPropertiesString = SystemHelper.ConvertListToTokenString(pairsLines, Environment.NewLine, false); + string dcaPropertiesString = SystemHelper.ConvertListToTokenString(dcaLines, Environment.NewLine, false); + string indicatorsPropertiesString = SystemHelper.ConvertListToTokenString(indicatorsLines, Environment.NewLine, false); + query += "&pairsData=" + WebUtility.UrlEncode(pairsPropertiesString) + "&dcaData=" + WebUtility.UrlEncode(dcaPropertiesString) + "&indicatorsData=" + WebUtility.UrlEncode(indicatorsPropertiesString); + byte[] formData = Encoding.ASCII.GetBytes(query); + httpWebRequest.ContentLength = formData.Length; + using (Stream stream = httpWebRequest.GetRequestStream()) + { + stream.Write(formData, 0, formData.Length); + } + log.DoLogDebug("Built POST request for Properties"); + int adjustedCount = i+1; + log.DoLogInfo("Sending Properties to license " + adjustedCount + " at " + urlList[i]); + using (HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse()) + { + log.DoLogInfo("Properties sent!"); + httpResponse.Close(); + log.DoLogDebug("Properties response object closed."); + } + + transferCompleted = true; } - log.DoLogDebug("Built POST request for Properties"); + catch (WebException ex) + { + // Manual error handling as PT doesn't seem to provide a proper error response... + if (ex.Message.IndexOf("401") > -1) + { + log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Unauthorized! The specified Profit Trailer license key '" + systemConfiguration.GetProfitTrailerLicenseKeyMasked() + "' is invalid!"); + transferCanceled = true; + } + else if (ex.Message.IndexOf("timed out") > -1) + { + // Handle timeout seperately + retryCount++; + if (retryCount <= maxRetries) + { + log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout! Starting retry number " + retryCount + "/" + maxRetries.ToString() + "!"); + } + else + { + transferCanceled = true; + log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout! Canceling transfer after " + maxRetries.ToString() + " failed retries."); + } + } + else + { + log.DoLogCritical("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': " + ex.Message, ex); + transferCanceled = true; + } - log.DoLogInfo("Sending Properties..."); - using (HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse()) - { - log.DoLogInfo("Properties sent!"); - httpResponse.Close(); - log.DoLogDebug("Properties response object closed."); } - - transferCompleted = true; - } - catch (WebException ex) - { - // Manual error handling as PT doesn't seem to provide a proper error response... - if (ex.Message.IndexOf("401") > -1) + catch (TimeoutException ex) { - log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Unauthorized! The specified Profit Trailer license key '" + systemConfiguration.GetProfitTrailerLicenseKeyMasked() + "' is invalid!"); - transferCanceled = true; - } - else if (ex.Message.IndexOf("timed out") > -1) - { - // Handle timeout seperately retryCount++; if (retryCount <= maxRetries) { - log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout! Starting retry number " + retryCount + "/" + maxRetries.ToString() + "!"); + log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout (" + ex.Message + ")! Starting retry number " + retryCount + "/" + maxRetries.ToString() + "!"); } else { transferCanceled = true; - log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout! Canceling transfer after " + maxRetries.ToString() + " failed retries."); + log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout (" + ex.Message + ")! Canceling transfer after " + maxRetries.ToString() + " failed retries."); } } - else + catch (Exception ex) { log.DoLogCritical("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': " + ex.Message, ex); transferCanceled = true; } - - } - catch (TimeoutException ex) - { - retryCount++; - if (retryCount <= maxRetries) - { - log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout (" + ex.Message + ")! Starting retry number " + retryCount + "/" + maxRetries.ToString() + "!"); - } - else - { - transferCanceled = true; - log.DoLogError("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': Timeout (" + ex.Message + ")! Canceling transfer after " + maxRetries.ToString() + " failed retries."); - } - } - catch (Exception ex) - { - log.DoLogCritical("Saving Properties failed for setting '" + systemConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName + "': " + ex.Message, ex); - transferCanceled = true; } } + + } } } \ No newline at end of file diff --git a/Core/ProfitTrailer/SettingsHandler.cs b/Core/ProfitTrailer/SettingsHandler.cs index 71bac93..c119c64 100644 --- a/Core/ProfitTrailer/SettingsHandler.cs +++ b/Core/ProfitTrailer/SettingsHandler.cs @@ -144,9 +144,8 @@ namespace Core.ProfitTrailer foreach (string line in pairsLines) { - if (line.Replace(" ", "").StartsWith("ALL_enabled_pairs", StringComparison.InvariantCultureIgnoreCase) || line.Replace(" ", "").StartsWith("enabled_pairs", StringComparison.InvariantCultureIgnoreCase)) + if (line.Replace(" ", "").StartsWith("enabled_pairs", StringComparison.InvariantCultureIgnoreCase)) { - result = line.Replace("ALL_enabled_pairs", "", StringComparison.InvariantCultureIgnoreCase); result = result.Replace("enabled_pairs", "", StringComparison.InvariantCultureIgnoreCase); result = result.Replace("#", ""); result = result.Replace("=", "").Trim(); @@ -644,4 +643,4 @@ namespace Core.ProfitTrailer } #endregion } -} +} \ No newline at end of file diff --git a/Core/ProfitTrailer/StrategyHelper.cs b/Core/ProfitTrailer/StrategyHelper.cs index b211fe0..cdd873b 100644 --- a/Core/ProfitTrailer/StrategyHelper.cs +++ b/Core/ProfitTrailer/StrategyHelper.cs @@ -272,7 +272,7 @@ namespace Core.ProfitTrailer if (!string.IsNullOrEmpty(strategyName)) { // buy/sell strategies beginning with PT 2.3.3 contain the letter followed by a colon and space. - if (strategyName.Contains(":")) + if (strategyName.Contains(":") && !strategyName.Contains("FORMULA")) { result = true; } diff --git a/Monitor/Pages/SalesAnalyzer.cshtml b/Monitor/Pages/SalesAnalyzer.cshtml index 79e99b7..f75c554 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml +++ b/Monitor/Pages/SalesAnalyzer.cshtml @@ -62,14 +62,7 @@

Sales Analysis

@{ double totalProfit = 0; - if (Model.PTData.Properties.Shorting) - { - totalProfit = Model.PTData.SellLog.Sum(s => s.Profit * (-1)); - } - else - { - totalProfit = Model.PTData.SellLog.Sum(s => s.Profit); - } + totalProfit = Model.PTData.SellLog.Sum(s => s.Profit); double totalProfitFiat = Math.Round(totalProfit * Model.Summary.MainMarketPrice, 2); double percentGain = Math.Round(totalProfit / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance * 100, 2); double avgDailyGain = Model.DailyGains.Values.Average(dg => dg); @@ -205,14 +198,7 @@ @for (DateTime salesDate = Model.DateTimeNow.DateTime.Date; salesDate >= Model.DateTimeNow.DateTime.AddDays(-Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxDailySummaries) && salesDate >= Model.MinSellLogDate; salesDate = salesDate.AddDays(-1)) { List salesDateSales = Model.PTData.SellLog.FindAll(sl => sl.SoldDate.Date == salesDate); double salesDateProfit = 0; - if (Model.PTData.Properties.Shorting) - { - salesDateProfit = salesDateSales.Sum(sl => sl.Profit * (-1)); - } - else - { - salesDateProfit = salesDateSales.Sum(sl => sl.Profit); - } + salesDateProfit = salesDateSales.Sum(sl => sl.Profit); double salesDateProfitFiat = Math.Round(salesDateProfit * Model.Summary.MainMarketPrice, 2); double salesDateStartBalance = Model.PTData.GetSnapshotBalance(salesDate); double salesDateGain = Math.Round(salesDateProfit / salesDateStartBalance * 100, 2); @@ -252,14 +238,7 @@ @for (DateTime salesMonthDate = salesMonthStartDate.Date; salesMonthDate >= Model.DateTimeNow.DateTime.AddMonths(-Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxMonthlySummaries) && salesMonthDate >= minSellLogMonthDate; salesMonthDate = salesMonthDate.AddMonths(-1)) { List salesMonthSales = Model.PTData.SellLog.FindAll(sl => sl.SoldDate.Date.Month == salesMonthDate.Month && sl.SoldDate.Date.Year == salesMonthDate.Year); double salesDateProfit = 0; - if (Model.PTData.Properties.Shorting) - { - salesDateProfit = salesMonthSales.Sum(sl => sl.Profit * (-1)); - } - else - { - salesDateProfit = salesMonthSales.Sum(sl => sl.Profit); - } + salesDateProfit = salesMonthSales.Sum(sl => sl.Profit); double salesDateProfitFiat = Math.Round(salesDateProfit * Model.Summary.MainMarketPrice, 2); double salesDateStartBalance = Model.PTData.GetSnapshotBalance(salesMonthDate); double salesDateGain = Math.Round(salesDateProfit / salesDateStartBalance * 100, 2); @@ -272,14 +251,7 @@ days++; List monthDaySales = Model.PTData.SellLog.FindAll(sl => sl.SoldDate.Date == monthDay.Date); double monthDayProfit = 0; - if (Model.PTData.Properties.Shorting) - { - monthDayProfit = monthDaySales.Sum(sl => sl.Profit * (-1)); - } - else - { - monthDayProfit = monthDaySales.Sum(sl => sl.Profit); - } + monthDayProfit = monthDaySales.Sum(sl => sl.Profit); double monthDayStartBalance = Model.PTData.GetSnapshotBalance(monthDay); monthDailyProfit += Math.Round(monthDayProfit / monthDayStartBalance * 100, 2); } @@ -319,10 +291,6 @@ @{ var topMarkets = Model.PTData.SellLog.GroupBy(m => m.Market).Select(mg => mg.Sum(m => m.Profit)); - if (Model.PTData.Properties.Shorting) - { - topMarkets = Model.PTData.SellLog.GroupBy(m => m.Market).Select(mg => mg.Sum(m => m.Profit) * (-1)); - } int marketRank = 0; } @foreach (KeyValuePair marketData in Model.TopMarkets) { diff --git a/Monitor/Pages/SalesAnalyzer.cshtml.cs b/Monitor/Pages/SalesAnalyzer.cshtml.cs index 1b2a00f..74d1b73 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml.cs +++ b/Monitor/Pages/SalesAnalyzer.cshtml.cs @@ -46,14 +46,7 @@ namespace Monitor.Pages foreach (var market in markets) { double totalProfit = 0; - if (PTData.Properties.Shorting) - { - totalProfit = PTData.SellLog.FindAll(m => m.Market == market.Key).Sum(m => m.Profit * (-1)); - } - else - { - totalProfit = PTData.SellLog.FindAll(m => m.Market == market.Key).Sum(m => m.Profit); - } + totalProfit = PTData.SellLog.FindAll(m => m.Market == market.Key).Sum(m => m.Profit); topMarketsDic.Add(market.Key, totalProfit); } TopMarkets = new SortedDictionary(topMarketsDic).OrderByDescending(m => m.Value).Take(PTMagicConfiguration.GeneralSettings.Monitor.MaxTopMarkets); @@ -81,14 +74,7 @@ namespace Monitor.Pages } double profit = 0; int trades = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Count; - if (PTData.Properties.Shorting) - { - profit = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Sum(t => t.Profit * (-1)); - } - else - { - profit = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Sum(t => t.Profit); - } + profit = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Sum(t => t.Profit); double profitFiat = Math.Round(profit * Summary.MainMarketPrice, 2); balance += profitFiat; tradesPerDayJSON += "{x: new Date('" + salesDate.Date.ToString("yyyy-MM-dd") + "'), y: " + trades + "}"; @@ -124,14 +110,7 @@ namespace Monitor.Pages { List salesDateSales = PTData.SellLog.FindAll(sl => sl.SoldDate.Date == salesDate); double salesDateProfit; - if (PTData.Properties.Shorting) - { - salesDateProfit = salesDateSales.Sum(sl => sl.Profit * (-1)); - } - else - { - salesDateProfit = salesDateSales.Sum(sl => sl.Profit); - } + salesDateProfit = salesDateSales.Sum(sl => sl.Profit); double salesDateStartBalance = PTData.GetSnapshotBalance(salesDate); double salesDateGain = Math.Round(salesDateProfit / salesDateStartBalance * 100, 2); DailyGains.Add(salesDate, salesDateGain); @@ -142,14 +121,7 @@ namespace Monitor.Pages { List salesMonthSales = PTData.SellLog.FindAll(sl => sl.SoldDate.Date.Month == salesMonthDate.Month && sl.SoldDate.Date.Year == salesMonthDate.Year); double salesDateProfit; - if (PTData.Properties.Shorting) - { - salesDateProfit = salesMonthSales.Sum(sl => sl.Profit * (-1)); - } - else - { - salesDateProfit = salesMonthSales.Sum(sl => sl.Profit); - } + salesDateProfit = salesMonthSales.Sum(sl => sl.Profit); double salesDateStartBalance = PTData.GetSnapshotBalance(salesMonthDate); double salesDateGain = Math.Round(salesDateProfit / salesDateStartBalance * 100, 2); MonthlyGains.Add(salesMonthDate, salesDateGain); diff --git a/Monitor/Pages/SettingsGeneral.cshtml b/Monitor/Pages/SettingsGeneral.cshtml index bd8a46a..4989f93 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml +++ b/Monitor/Pages/SettingsGeneral.cshtml @@ -48,24 +48,30 @@
- +
- +
- -
- @Model.PTMagicConfiguration.GeneralSettings.Application.Exchange -
+ +
+ +
@@ -77,16 +83,16 @@
- +
- @Model.PTMagicConfiguration.GetProfitTrailerServerAPITokenMasked() +
@@ -170,28 +176,21 @@
- +
- +
- @Model.PTMagicConfiguration.GeneralSettings.Monitor.Port +
- -
- @Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl -
-
- -
- +
diff --git a/Monitor/Pages/SettingsGeneral.cshtml.cs b/Monitor/Pages/SettingsGeneral.cshtml.cs index 5a031e3..d5f3c1e 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml.cs +++ b/Monitor/Pages/SettingsGeneral.cshtml.cs @@ -70,19 +70,19 @@ namespace Monitor.Pages PTMagicConfiguration.GeneralSettings.Application.TestMode = HttpContext.Request.Form["Application_TestMode"].Equals("on"); PTMagicConfiguration.GeneralSettings.Application.StartBalance = SystemHelper.TextToDouble(HttpContext.Request.Form["Application_StartBalance"], PTMagicConfiguration.GeneralSettings.Application.StartBalance, "en-US"); PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName = HttpContext.Request.Form["Application_ProfitTrailerDefaultSettingName"]; - + PTMagicConfiguration.GeneralSettings.Application.Exchange = HttpContext.Request.Form["Application_Exchange"]; + PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL = HttpContext.Request.Form["Application_ProfitTrailerMonitorURL"]; + PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken = HttpContext.Request.Form["Application_ProfitTrailerServerAPIToken"]; PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset = HttpContext.Request.Form["Application_TimezoneOffset"]; PTMagicConfiguration.GeneralSettings.Application.MainFiatCurrency = HttpContext.Request.Form["Application_MainFiatCurrency"]; - - PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes = SystemHelper.TextToInteger(HttpContext.Request.Form["Application_FloodProtectionMinutes"], PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes); PTMagicConfiguration.GeneralSettings.Application.InstanceName = HttpContext.Request.Form["Application_InstanceName"]; PTMagicConfiguration.GeneralSettings.Application.CoinMarketCapAPIKey = HttpContext.Request.Form["Application_CoinMarketCapAPIKey"]; PTMagicConfiguration.GeneralSettings.Application.FreeCurrencyConverterAPIKey = HttpContext.Request.Form["Application_FreeCurrencyConverterAPIKey"]; - PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected = HttpContext.Request.Form["Monitor_IsPasswordProtected"].Equals("on"); PTMagicConfiguration.GeneralSettings.Monitor.OpenBrowserOnStart = HttpContext.Request.Form["Monitor_OpenBrowserOnStart"].Equals("on"); - PTMagicConfiguration.GeneralSettings.Monitor.DefaultDCAMode = HttpContext.Request.Form["Monitor_AnalyzerChart"]; + PTMagicConfiguration.GeneralSettings.Monitor.AnalyzerChart = HttpContext.Request.Form["Monitor_AnalyzerChart"]; + PTMagicConfiguration.GeneralSettings.Monitor.Port = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_Port"], PTMagicConfiguration.GeneralSettings.Monitor.Port); PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_GraphIntervalMinutes"], PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes); PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_GraphMaxTimeframeHours"], PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours); PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_RefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds); diff --git a/Monitor/Pages/_get/BagDetails.cshtml b/Monitor/Pages/_get/BagDetails.cshtml index 087a4e1..2c5e4f8 100644 --- a/Monitor/Pages/_get/BagDetails.cshtml +++ b/Monitor/Pages/_get/BagDetails.cshtml @@ -103,7 +103,7 @@ diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 03cff44..823b6f6 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -121,14 +121,7 @@ @{ double totalProfit = 0; - if (Model.PTData.Properties.Shorting) - { - totalProfit = Model.PTData.SellLog.Sum(s => s.Profit * (-1)); - } - else - { - totalProfit = Model.PTData.SellLog.Sum(s => s.Profit); - } + totalProfit = Model.PTData.SellLog.Sum(s => s.Profit); double totalProfitFiat = Math.Round(totalProfit * Model.Summary.MainMarketPrice, 2); double percentGain = Math.Round(totalProfit / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance * 100, 2); string percentGainText = percentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%"; @@ -138,53 +131,25 @@ } double todaysProfit = 0; - if (Model.PTData.Properties.Shorting) - { - todaysProfit = Model.PTData.SellLogToday.Sum(s => s.Profit * (-1)); - } - else - { - todaysProfit = Model.PTData.SellLogToday.Sum(s => s.Profit); - } + todaysProfit = Model.PTData.SellLogToday.Sum(s => s.Profit); double todaysStartBalance = Model.PTData.GetSnapshotBalance(Model.DateTimeNow.DateTime); double todaysProfitFiat = Math.Round(todaysProfit * Model.Summary.MainMarketPrice, 2); double todaysPercentGain = Math.Round(todaysProfit / todaysStartBalance * 100, 2); double yesterdaysProfit = 0; - if (Model.PTData.Properties.Shorting) - { - yesterdaysProfit = Model.PTData.SellLogYesterday.Sum(s => s.Profit * (-1)); - } - else - { - yesterdaysProfit = Model.PTData.SellLogYesterday.Sum(s => s.Profit); - } + yesterdaysProfit = Model.PTData.SellLogYesterday.Sum(s => s.Profit); double yesterdaysStartBalance = Model.PTData.GetSnapshotBalance(Model.DateTimeNow.DateTime.AddDays(-1)); double yesterdaysProfitFiat = Math.Round(yesterdaysProfit * Model.Summary.MainMarketPrice, 2); double yesterdaysPercentGain = Math.Round(yesterdaysProfit / yesterdaysStartBalance * 100, 2); double last7DaysProfit = 0; - if (Model.PTData.Properties.Shorting) - { - last7DaysProfit = Model.PTData.SellLogLast7Days.Sum(s => s.Profit * (-1)); - } - else - { - last7DaysProfit = Model.PTData.SellLogLast7Days.Sum(s => s.Profit); - } + last7DaysProfit = Model.PTData.SellLogLast7Days.Sum(s => s.Profit); double last7DaysStartBalance = Model.PTData.GetSnapshotBalance(Model.DateTimeNow.DateTime.AddDays(-7)); double last7DaysProfitFiat = Math.Round(last7DaysProfit * Model.Summary.MainMarketPrice, 2); double last7DaysPercentGain = Math.Round(last7DaysProfit / last7DaysStartBalance * 100, 2); double last30DaysProfit = 0; - if (Model.PTData.Properties.Shorting) - { - last30DaysProfit = Model.PTData.SellLogLast30Days.Sum(s => s.Profit * (-1)); - } - else - { - last30DaysProfit = Model.PTData.SellLogLast30Days.Sum(s => s.Profit); - } + last30DaysProfit = Model.PTData.SellLogLast30Days.Sum(s => s.Profit); double last30DaysStartBalance = Model.PTData.GetSnapshotBalance(Model.DateTimeNow.DateTime.AddDays(-30)); double last30DaysProfitFiat = Math.Round(last30DaysProfit * Model.Summary.MainMarketPrice, 2); double last30DaysPercentGain = Math.Round(last30DaysProfit / last30DaysStartBalance * 100, 2); diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs index 5eb3390..0ff5157 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs +++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs @@ -145,10 +145,6 @@ namespace Monitor.Pages } int trades = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate).Count; double profit = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate).Sum(t => t.Profit); - if (PTData.Properties.Shorting) - { - profit = profit * (-1); - } double profitFiat = Math.Round(profit * Summary.MainMarketPrice, 2); profitPerDayJSON += "{x: new Date('" + salesDate.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"; tradeDayIndex++; diff --git a/Monitor/Pages/_get/DashboardTop.cshtml b/Monitor/Pages/_get/DashboardTop.cshtml index 80d5569..9bdb3b4 100644 --- a/Monitor/Pages/_get/DashboardTop.cshtml +++ b/Monitor/Pages/_get/DashboardTop.cshtml @@ -98,10 +98,9 @@ 24H Cost - DCA - Sell - Target - Profit + DCA + Sell + Profit @@ -202,42 +201,32 @@ @Html.Raw(buyStrategyText) @Html.Raw(sellStrategyText) - - @if (!sellStrategyText.Contains("WATCHMODE")) - { - @if (sellStrategyText.Contains("CROSSED")) - // if leverage, recalculate profit target - { - string leverageText = sellStrategyText.Remove(0, sellStrategyText.IndexOf("CROSSED")+9); - leverage = leverageText.Remove(leverageText.IndexOf(".0)"), leverageText.Length - leverageText.IndexOf(".0)")); - leverageValue = double.Parse(leverage); - } - @if (sellStrategyText.Contains("ISOLATED")) - { - string leverageText = sellStrategyText.Remove(0, sellStrategyText.IndexOf("ISOLATED")+10); - leverage = leverageText.Remove(leverageText.IndexOf(".0)"), leverageText.Length - leverageText.IndexOf(".0)")); - leverageValue = double.Parse(leverage); - } - @if (leverageValue == 1) - { - @Html.Raw(dcaLogEntry.TargetGainValue.HasValue ? dcaLogEntry.TargetGainValue.Value.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%" : " ") - } - else - { - double TargetGain = leverageValue * dcaLogEntry.TargetGainValue.Value; - @Html.Raw(dcaLogEntry.TargetGainValue.HasValue ? TargetGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%" : " ") - } - } - else - { - - } - + @if (!@lostValue) - { - profitPercentage = profitPercentage * leverageValue; - @profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))% - } + { + @if (!sellStrategyText.Contains("WATCHMODE")) + { + @if (sellStrategyText.Contains("CROSSED")) + // if leverage, recalculate profit target + { + string leverageText = sellStrategyText.Remove(0, sellStrategyText.IndexOf("CROSSED")+9); + leverage = leverageText.Remove(leverageText.IndexOf(".0)"), leverageText.Length - leverageText.IndexOf(".0)")); + leverageValue = double.Parse(leverage); + } + @if (sellStrategyText.Contains("ISOLATED")) + { + string leverageText = sellStrategyText.Remove(0, sellStrategyText.IndexOf("ISOLATED")+10); + leverage = leverageText.Remove(leverageText.IndexOf(".0)"), leverageText.Length - leverageText.IndexOf(".0)")); + leverageValue = double.Parse(leverage); + } + profitPercentage = profitPercentage * leverageValue; + double TargetGain = leverageValue * dcaLogEntry.TargetGainValue.Value; + @TargetGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))% +
+
@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
+ + } + } else { No Value! @@ -258,7 +247,6 @@ - @Html.Raw((((Model.TotalBagGain) / Model.TotalBagCost) * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))% diff --git a/Monitor/Pages/_get/TickerWidgets.cshtml b/Monitor/Pages/_get/TickerWidgets.cshtml index 7f2fb03..89d2529 100644 --- a/Monitor/Pages/_get/TickerWidgets.cshtml +++ b/Monitor/Pages/_get/TickerWidgets.cshtml @@ -11,24 +11,29 @@ } // Global setting tool tip - string globalSettingInfoIcon = "Instance: " + Model.PTMagicConfiguration.GeneralSettings.Application.InstanceName + "\" data-template=\"\">"; + string globalIconColor = "text-success"; + string globalSettingInfoIcon = "Instance: " + Model.PTMagicConfiguration.GeneralSettings.Application.InstanceName + "\" data-template=\"\">"; + if (Model.PTData.Properties.Shorting) + { + globalIconColor = "text-danger"; + } // Health indicator DateTime lastRuntime = Model.Summary.LastRuntime; double elapsedSecondsSinceRuntime = DateTime.UtcNow.Subtract(lastRuntime).TotalSeconds; double intervalSeconds = Model.PTMagicConfiguration.AnalyzerSettings.MarketAnalyzer.IntervalMinutes * 60.0; - string iconColor = "text-success"; + string healthIconColor = "text-success"; string ptMagicHealthIcon = "fa-heartbeat"; string ptMagicHealthTooltip = "PT Magic is alive and healthy! Time elapsed since last run: " + Math.Round(elapsedSecondsSinceRuntime / 60, 1) + " mins."; if (elapsedSecondsSinceRuntime > (intervalSeconds * 2)) { ptMagicHealthIcon = "fa-exclamation-triangle"; ptMagicHealthTooltip = "PT Magic seems to have problems, check the logs! Time elapsed since last run: " + Math.Round(elapsedSecondsSinceRuntime / 60, 1) + " mins."; - iconColor = "text-danger"; + healthIconColor = "text-danger"; } } -
+
@Core.Helper.SystemHelper.SplitCamelCase(Model.Summary.CurrentGlobalSetting.SettingName)@Html.Raw(" " + globalSettingInfoIcon)
@@ -37,8 +42,8 @@ SMS: @Html.Raw(activeSingleSettings + " " + singleSettingInfoIcon)
-
- +
+