From 6aa6928376140185f1bde28267211c8df64bee4a Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Wed, 24 Jan 2024 03:05:28 +0900 Subject: [PATCH 01/19] LIVE TCV / TV Layout / Timezone / Cosmetics --- Core/DataObjects/PTMagicData.cs | 7 +- Core/DataObjects/ProfitTrailerData.cs | 90 +++------ Core/Helper/SystemHelper.cs | 12 +- Monitor/Pages/Index.cshtml | 28 ++- Monitor/Pages/ManageSMS.cshtml | 2 +- Monitor/Pages/MarketAnalyzer.cshtml | 8 +- Monitor/Pages/MarketAnalyzer.cshtml.cs | 10 +- Monitor/Pages/SalesAnalyzer.cshtml | 2 +- Monitor/Pages/SalesAnalyzer.cshtml.cs | 18 +- Monitor/Pages/SettingsGeneral.cshtml | 30 +-- Monitor/Pages/SettingsGeneral.cshtml.cs | 29 +-- Monitor/Pages/StatusSummary.cshtml | 7 +- Monitor/Pages/StatusSummary.cshtml.cs | 5 + Monitor/Pages/Transactions.cshtml | 174 ------------------ Monitor/Pages/Transactions.cshtml.cs | 78 -------- Monitor/Pages/_get/BagDetails.cshtml | 2 +- Monitor/Pages/_get/BagDetails.cshtml.cs | 6 +- Monitor/Pages/_get/BagList.cshtml | 4 +- Monitor/Pages/_get/BuyList.cshtml | 4 +- Monitor/Pages/_get/DashboardBottom.cshtml | 136 ++++++++++---- Monitor/Pages/_get/DashboardBottom.cshtml.cs | 112 ++++++++++- Monitor/Pages/_get/DashboardTop.cshtml | 122 ++++++------ Monitor/Pages/_get/DashboardTop.cshtml.cs | 7 +- .../settings.general.json | 2 +- .../DevSettings/settings.general.json | 2 +- 25 files changed, 376 insertions(+), 521 deletions(-) delete mode 100644 Monitor/Pages/Transactions.cshtml delete mode 100644 Monitor/Pages/Transactions.cshtml.cs diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index 3f80cd4..be534bc 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -42,7 +42,7 @@ namespace Core.Main.DataObjects.PTMagicData public int FloodProtectionMinutes { get; set; } = 15; public string Exchange { get; set; } public string InstanceName { get; set; } = "PT Magic"; - public string TimezoneOffset { get; set; } = "+0:00"; + //public string TimezoneOffset { get; set; } = "+0:00"; public string CoinMarketCapAPIKey { get; set; } //public string FreeCurrencyConverterAPIKey { get; set; } } @@ -55,13 +55,13 @@ namespace Core.Main.DataObjects.PTMagicData public bool OpenBrowserOnStart { get; set; } = false; public int Port { get; set; } = 5000; public string AnalyzerChart { get; set; } = ""; + public int LiveTCVTimeframeMinutes { get; set; } = 60; public int GraphIntervalMinutes { get; set; } = 60; public int GraphMaxTimeframeHours { get; set; } = 24; public int ProfitsMaxTimeframeDays { get; set; } = 60; public int RefreshSeconds { get; set; } = 30; public int BagAnalyzerRefreshSeconds { get; set; } = 5; public int BuyAnalyzerRefreshSeconds { get; set; } = 5; - //public int MaxSalesRecords { get; set; } = 99999; public int MaxTopMarkets { get; set; } = 20; public int MaxDailySummaries { get; set; } = 10; public int MaxMonthlySummaries { get; set; } = 10; @@ -70,6 +70,7 @@ namespace Core.Main.DataObjects.PTMagicData public int MaxDCAPairs { get; set; } = 24; public int MaxSettingsLogEntries { get; set; } = 20; public string LinkPlatform { get; set; } = "TradingView"; + public string TVCustomLayout { get; set; } = ""; public string DefaultDCAMode { get; set; } = "Simple"; public string TvStudyA { get; set; } = ""; public string TvStudyB { get; set; } = ""; @@ -572,5 +573,7 @@ namespace Core.Main.DataObjects.PTMagicData public string Market { get; set; } public string TotalCurrentValue { get; set; } public string TimeZoneOffset { get; set; } + public string ExchangeURL { get; set; } + public string PTVersion { get; set; } } } \ No newline at end of file diff --git a/Core/DataObjects/ProfitTrailerData.cs b/Core/DataObjects/ProfitTrailerData.cs index c96c69d..13c2050 100644 --- a/Core/DataObjects/ProfitTrailerData.cs +++ b/Core/DataObjects/ProfitTrailerData.cs @@ -82,8 +82,11 @@ namespace Core.Main.DataObjects { if (!_offsetTimeSpan.HasValue) { - // Get offset for settings. - _offsetTimeSpan = TimeSpan.Parse(_systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); + // Ensure Misc is populated + var misc = this.Misc; + + // Get offset from Misc + _offsetTimeSpan = TimeSpan.Parse(misc.TimeZoneOffset); } return _offsetTimeSpan.Value; @@ -133,6 +136,8 @@ namespace Core.Main.DataObjects StartBalance = PTData.startBalance, TotalCurrentValue = PTData.totalCurrentValue, TimeZoneOffset = PTData.timeZoneOffset, + ExchangeURL = PTData.exchangeUrl, + PTVersion = PTData.version, }; } public List DailyStats @@ -585,57 +590,6 @@ namespace Core.Main.DataObjects Order = monthlyStatsDataJson["order"], }; } -// public List SellLog -// { -// get -// { - -// if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh)) -// { -// lock (_sellLock) -// { -// // Thread double locking -// if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh)) -// { -// _sellLog.Clear(); - - -// // Page through the sales data summarizing it. -// bool exitLoop = false; -// int pageIndex = 1; - -// // 1 record per page to allow user to set max records to retrieve -// int maxPages = _systemConfiguration.GeneralSettings.Monitor.MaxSalesRecords; -// int requestedPages = 0; - -// while (!exitLoop && requestedPages < maxPages) -// { -// var sellDataPage = GetDataFromProfitTrailer("/api/v2/data/sales?Page=1&perPage=1&sort=SOLDDATE&sortDirection=DESCENDING&page=" + pageIndex); -// if (sellDataPage != null && sellDataPage.data.Count > 0) -// { -// // Add sales data page to collection -// this.BuildSellLogData(sellDataPage); -// pageIndex++; -// requestedPages++; -// Console.WriteLine($"Importing salesLog: {pageIndex}"); - -// } -// else -// { -// // All data retrieved -// exitLoop = true; -// } -// } - -// // Update sell log refresh time -// _sellLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds -1); -// } -// } -// } -// return _sellLog; -// } -// } - public List DCALog { @@ -677,26 +631,30 @@ namespace Core.Main.DataObjects return _dcaLog; } } - + public List BuyLog { get { - if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh)) - { - lock (_buyLock) + if (_systemConfiguration.GeneralSettings.Monitor.MaxDashboardBuyEntries == 0) { - // Thread double locking - if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh)) - { - _buyLog.Clear(); - this.BuildBuyLogData(GetDataFromProfitTrailer("/api/v2/data/pbl", true)); - _buyLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds - 1); - } + return _buyLog; } - } - return _buyLog; + if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh)) + { + lock (_buyLock) + { + if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh)) + { + _buyLog.Clear(); + this.BuildBuyLogData(GetDataFromProfitTrailer("/api/v2/data/pbl", true)); + _buyLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds - 1); + } + } + } + + return _buyLog; } } diff --git a/Core/Helper/SystemHelper.cs b/Core/Helper/SystemHelper.cs index 9687e39..f2564f2 100644 --- a/Core/Helper/SystemHelper.cs +++ b/Core/Helper/SystemHelper.cs @@ -1,6 +1,4 @@ using System; -using System.Text.RegularExpressions; -using System.IO; using System.Collections; using System.Collections.Generic; using System.Net; @@ -535,18 +533,22 @@ namespace Core.Helper } } - public static string GetMarketLink(string platform, string exchange, string market, string mainMarket) + public static string GetMarketLink(string platform, string exchange, string market, string mainMarket, string tvCustomLayout) { string result = "#"; + if (tvCustomLayout.Length > 0) + { + tvCustomLayout += "/"; + } if (platform.Equals("TradingView")) { if (exchange.Equals("binancefutures", StringComparison.InvariantCultureIgnoreCase)) { - result = "https://uk.tradingview.com/chart/?symbol=BINANCE:" + market.ToUpper() + "PERP"; + result = "https://uk.tradingview.com/chart/"+tvCustomLayout+"?symbol=BINANCE:" + market.ToUpper() + ".P"; } else { - result = "https://uk.tradingview.com/chart/?symbol=" + exchange.ToUpper() + ":" + market.ToUpper(); + result = "https://uk.tradingview.com/chart/"+tvCustomLayout+"?symbol=" + exchange.ToUpper() + ":" + market.ToUpper(); } } else diff --git a/Monitor/Pages/Index.cshtml b/Monitor/Pages/Index.cshtml index 770f037..25b691c 100644 --- a/Monitor/Pages/Index.cshtml +++ b/Monitor/Pages/Index.cshtml @@ -63,21 +63,8 @@ }; var loadDashboardBottom = function () { - //destroy all d3 svg graph to avoid memory leak - setTimeout(function() - { - $(".nvtooltip").remove(); - $("svg > *").remove(); - $("svg").remove(); - nv.charts = {}; - nv.graphs = []; - nv.logs = {}; - nv.tooltip = {}; - }, 10 * intervalDashboardBottom * 1000); // 10 times intervalDashboardBottom in milliseconds - - // Clear exisitng interval to stop multiple attempts to load at the same time. - if (intervalDashboardBottom != null) - { + // Clear existing interval to stop multiple attempts to load at the same time. + if (intervalDashboardBottom != null) { clearInterval(intervalDashboardBottom); } @@ -92,6 +79,17 @@ window.location.replace("@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)Login"); } else { errCountIndex["DashboardBottom"] = 0; + + // Destroy all d3 svg graph to avoid memory leak + setTimeout(function() { + $(".nvtooltip").remove(); + $("svg > *").remove(); + $("svg").remove(); + nv.charts = {}; + nv.graphs = []; + nv.logs = {}; + nv.tooltip = {}; + }, 30 * @Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000); // every 30 refreshes } // Reinstate the interval. diff --git a/Monitor/Pages/ManageSMS.cshtml b/Monitor/Pages/ManageSMS.cshtml index d9200d3..9bbc67b 100644 --- a/Monitor/Pages/ManageSMS.cshtml +++ b/Monitor/Pages/ManageSMS.cshtml @@ -69,7 +69,7 @@ @if (!lastMarket.Equals(smsSummary.Market)) { - @smsSummary.Market + @smsSummary.Market } diff --git a/Monitor/Pages/MarketAnalyzer.cshtml b/Monitor/Pages/MarketAnalyzer.cshtml index 304212f..a1e86dd 100644 --- a/Monitor/Pages/MarketAnalyzer.cshtml +++ b/Monitor/Pages/MarketAnalyzer.cshtml @@ -271,9 +271,9 @@ else } @if (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { - @market + @market } else { - @market + @market } @mps.LatestPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainMarket @Math.Round(mps.Latest24hVolume, 0).ToString("#,#0", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainMarket @@ -336,9 +336,9 @@ else } @if (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { - @market + @market } else { - @market + @market } @mps.LatestPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")) @Math.Round(mps.Latest24hVolume, 0).ToString("#,#0", new System.Globalization.CultureInfo("en-US")) diff --git a/Monitor/Pages/MarketAnalyzer.cshtml.cs b/Monitor/Pages/MarketAnalyzer.cshtml.cs index be4faf6..8b4d780 100644 --- a/Monitor/Pages/MarketAnalyzer.cshtml.cs +++ b/Monitor/Pages/MarketAnalyzer.cshtml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Core.Main; using Core.Helper; +using Core.Main.DataObjects; using Core.Main.DataObjects.PTMagicData; using System.Globalization; @@ -11,6 +12,8 @@ namespace Monitor.Pages public class MarketAnalyzerModel : _Internal.BasePageModelSecure { public List MarketTrends { get; set; } = new List(); + public ProfitTrailerData PTData = null; + public MiscData MiscData { get; set; } public string TrendChartDataJSON = ""; public double DataHours { get; set; } @@ -22,7 +25,8 @@ namespace Monitor.Pages private void BindData() { - // Get market trends + PTData = this.PtDataObject; + MiscData = this.PTData.Misc; MarketTrends = PTMagicConfiguration.AnalyzerSettings.MarketAnalyzer.MarketTrends.OrderBy(mt => mt.TrendMinutes).ThenByDescending(mt => mt.Platform).ToList(); BuildMarketTrendChartData(); @@ -56,8 +60,8 @@ namespace Monitor.Pages // Get trend ticks for chart TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { diff --git a/Monitor/Pages/SalesAnalyzer.cshtml b/Monitor/Pages/SalesAnalyzer.cshtml index 459f086..a3cb551 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml +++ b/Monitor/Pages/SalesAnalyzer.cshtml @@ -329,7 +329,7 @@ double profitFiat = Math.Round(profit * Model.MiscData.FiatConversionRate, 0); @rank - @coin + @coin @profit @sales @avg diff --git a/Monitor/Pages/SalesAnalyzer.cshtml.cs b/Monitor/Pages/SalesAnalyzer.cshtml.cs index dbe7c92..a37d9bd 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml.cs +++ b/Monitor/Pages/SalesAnalyzer.cshtml.cs @@ -54,7 +54,7 @@ namespace Monitor.Pages DailyStats = this.PTData.DailyStats; // Convert local offset time to UTC - TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); + TimeSpan offsetTimeSpan = TimeSpan.Parse(MiscData.TimeZoneOffset.Replace("+", "")); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan); BuildSalesChartData(); @@ -71,8 +71,8 @@ namespace Monitor.Pages { // Get timezone offset TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { @@ -129,8 +129,8 @@ namespace Monitor.Pages { // Get timezone offset TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { @@ -190,8 +190,8 @@ namespace Monitor.Pages { // Get timezone offset TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { @@ -301,8 +301,8 @@ namespace Monitor.Pages { // Get timezone offset TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { diff --git a/Monitor/Pages/SettingsGeneral.cshtml b/Monitor/Pages/SettingsGeneral.cshtml index 3b01e47..ba60241 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml +++ b/Monitor/Pages/SettingsGeneral.cshtml @@ -117,12 +117,12 @@ -
+ @*
-
+
*@ @*
@@ -196,42 +196,48 @@
- + +
+ +
+
+
+
- +
- +
- +
- +
- +
@@ -247,12 +253,12 @@
- @*
- +
+
- +
-
*@ +
diff --git a/Monitor/Pages/SettingsGeneral.cshtml.cs b/Monitor/Pages/SettingsGeneral.cshtml.cs index 85a10d4..a731e9b 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml.cs +++ b/Monitor/Pages/SettingsGeneral.cshtml.cs @@ -27,30 +27,6 @@ namespace Monitor.Pages return result; } - public string GetTimezoneSelection() - { - string result = ""; - - List tzOffsetList = new List(); - foreach (TimeZoneInfo tzi in TimeZoneInfo.GetSystemTimeZones()) - { - string offsetString = this.GetTimezoneOffsetString(tzi); - if (!tzOffsetList.Contains(offsetString)) - { - string selected = ""; - if (PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Equals(offsetString, StringComparison.InvariantCultureIgnoreCase)) - { - selected = " selected=\"selected\""; - } - - result += "" + offsetString + "\n"; - tzOffsetList.Add(offsetString); - } - } - - return result; - } - public void OnGet() { base.Init(); @@ -78,7 +54,7 @@ namespace Monitor.Pages 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.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"]; @@ -88,6 +64,7 @@ namespace Monitor.Pages PTMagicConfiguration.GeneralSettings.Monitor.OpenBrowserOnStart = HttpContext.Request.Form["Monitor_OpenBrowserOnStart"].Equals("on"); 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.LiveTCVTimeframeMinutes = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_LiveTCVTimeframeMinutes"], PTMagicConfiguration.GeneralSettings.Monitor.LiveTCVTimeframeMinutes); 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.ProfitsMaxTimeframeDays = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_ProfitsMaxTimeframeDays"], PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays); @@ -95,7 +72,7 @@ namespace Monitor.Pages PTMagicConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_BagAnalyzerRefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds); PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_BuyAnalyzerRefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds); PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform = HttpContext.Request.Form["Monitor_LinkPlatform"]; - //PTMagicConfiguration.GeneralSettings.Monitor.MaxSalesRecords = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_MaxSalesRecords"], PTMagicConfiguration.GeneralSettings.Monitor.MaxSalesRecords); + PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout = HttpContext.Request.Form["Monitor_TVCustomLayout"]; PTMagicConfiguration.GeneralSettings.Monitor.MaxTopMarkets = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_MaxTopMarkets"], PTMagicConfiguration.GeneralSettings.Monitor.MaxTopMarkets); PTMagicConfiguration.GeneralSettings.Monitor.MaxDailySummaries = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_MaxDailySummaries"], PTMagicConfiguration.GeneralSettings.Monitor.MaxDailySummaries); PTMagicConfiguration.GeneralSettings.Monitor.MaxMonthlySummaries = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_MaxMonthlySummaries"], PTMagicConfiguration.GeneralSettings.Monitor.MaxMonthlySummaries); diff --git a/Monitor/Pages/StatusSummary.cshtml b/Monitor/Pages/StatusSummary.cshtml index 7bab1c6..cb07c84 100644 --- a/Monitor/Pages/StatusSummary.cshtml +++ b/Monitor/Pages/StatusSummary.cshtml @@ -116,13 +116,8 @@
- - - - -

Global Settings Log

@@ -136,7 +131,7 @@ @foreach (Core.Main.DataObjects.PTMagicData.GlobalSettingSummary gss in Model.Summary.GlobalSettingSummary.OrderByDescending(g => g.SwitchDateTime).Take(Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxSettingsLogEntries)) { - TimeSpan offsetTimeSpan = TimeSpan.Parse(Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); + TimeSpan offsetTimeSpan = TimeSpan.Parse(Model.MiscData.TimeZoneOffset.Replace("+", "")); DateTimeOffset settingActivationTime = gss.SwitchDateTime; settingActivationTime = settingActivationTime.ToOffset(offsetTimeSpan); diff --git a/Monitor/Pages/StatusSummary.cshtml.cs b/Monitor/Pages/StatusSummary.cshtml.cs index 8532f09..6f78877 100644 --- a/Monitor/Pages/StatusSummary.cshtml.cs +++ b/Monitor/Pages/StatusSummary.cshtml.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.AspNetCore.Http; using Core.Main; using Core.Helper; +using Core.Main.DataObjects; using Core.Main.DataObjects.PTMagicData; namespace Monitor.Pages @@ -14,6 +15,8 @@ namespace Monitor.Pages public string SettingsDistribution24hChartDataJSON = ""; public string SettingsDistribution3dChartDataJSON = ""; private Dictionary settingsChartColors = new Dictionary(); + public ProfitTrailerData PTData = null; + public MiscData MiscData { get; set; } public void OnGet() { @@ -24,6 +27,8 @@ namespace Monitor.Pages private void BindData() { + PTData = this.PtDataObject; + MiscData = this.PTData.Misc; BuildMarketsWithSingleSettings(); BuildChartColors(); Build24hChartData(); diff --git a/Monitor/Pages/Transactions.cshtml b/Monitor/Pages/Transactions.cshtml deleted file mode 100644 index b41eb9a..0000000 --- a/Monitor/Pages/Transactions.cshtml +++ /dev/null @@ -1,174 +0,0 @@ -@page -@model TransactionsModel -@{ - ViewData["Title"] = ""; -} - -@section Styles { - - - -} - -
-
-
-

Transactions

- -

- In this area you may add manual transactions (like deposits and withdrawals) to your PT Magic data. Adding this kind of information will help PT Magic calculating your percentage gains and your balance more accurately. -

-
-
-
- -
-
-
-
-

New Transaction

- -
- -
- -
-
- -
- -
-
- - -
-
-
- -
- -
-
- - -
-
-
- -
- -
- -
-
-
-
-
- - @if (!Model.ValidationMessage.Equals("")) { -
-
-
- @Model.ValidationMessage -
-
-
- } - - - -
-
-
-

Your Transactions

- - @if (Model.TransactionData.Transactions.Count > 0) { -
- - - - - - - - - - @foreach (Core.Main.DataObjects.PTMagicData.Transaction transaction in Model.TransactionData.Transactions) { - - - - - @if (transaction.Amount > 0) { - - } else { - - } - - } - -
TimeAmountType
@transaction.GetLocalDateTime(Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset).ToShortDateString() @transaction.GetLocalDateTime(Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset).ToShortTimeString()@transaction.Amount.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))DepositWithdrawal
- } else { -

No transactions found.

- } -
- - - - - -@section Scripts { - - - - - - - -} diff --git a/Monitor/Pages/Transactions.cshtml.cs b/Monitor/Pages/Transactions.cshtml.cs deleted file mode 100644 index 8312f30..0000000 --- a/Monitor/Pages/Transactions.cshtml.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Http; -using Core.Main; -using Core.Helper; -using Core.Main.DataObjects; -using Core.Main.DataObjects.PTMagicData; -using System.Globalization; - -namespace Monitor.Pages -{ - public class TransactionsModel : _Internal.BasePageModelSecure - { - public TransactionData TransactionData = null; - public string ValidationMessage = ""; - - public void OnGet() - { - base.Init(); - - BindData(); - } - - private void BindData() - { - TransactionData = new TransactionData(PTMagicBasePath); - } - - public void OnPost() - { - base.Init(); - - BindData(); - - SaveTransaction(); - } - - private void SaveTransaction() - { - double transactionAmount = 0; - DateTimeOffset transactionDateTime = Constants.confMinDate; - - try - { - transactionAmount = SystemHelper.TextToDouble(HttpContext.Request.Form["Transaction_Amount"], transactionAmount, "en-US"); - //transactionDateTime = DateTimeOffset.Parse(HttpContext.Request.Form["Transaction_Date"] + " " + HttpContext.Request.Form["Transaction_Time"], CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); - DateTime tmp = DateTime.Parse(HttpContext.Request.Form["Transaction_Date"] + " " + HttpContext.Request.Form["Transaction_Time"], CultureInfo.InvariantCulture, DateTimeStyles.None); - - // Convert local offset time to UTC - TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); - transactionDateTime = new DateTimeOffset(tmp, offsetTimeSpan); - } - catch { } - - if (transactionAmount == 0) - { - ValidationMessage = "Please enter a valid amount in the format 123.45!"; - } - else - { - if (transactionDateTime == Constants.confMinDate) - { - ValidationMessage = "Please select a valid date and time!"; - } - else - { - TransactionData.Transactions.Add(new Transaction() { GUID = Guid.NewGuid().ToString(), Amount = transactionAmount, UTCDateTime = transactionDateTime.UtcDateTime }); - TransactionData.SaveTransactions(PTMagicBasePath); - - NotifyHeadline = "Transaction saved!"; - NotifyMessage = "Transaction saved successfully to _data/Transactions.json."; - NotifyType = "success"; - } - } - } - } -} diff --git a/Monitor/Pages/_get/BagDetails.cshtml b/Monitor/Pages/_get/BagDetails.cshtml index aba6d69..30bb6a4 100644 --- a/Monitor/Pages/_get/BagDetails.cshtml +++ b/Monitor/Pages/_get/BagDetails.cshtml @@ -103,7 +103,7 @@ diff --git a/Monitor/Pages/_get/BagDetails.cshtml.cs b/Monitor/Pages/_get/BagDetails.cshtml.cs index b6e651b..e1463b6 100644 --- a/Monitor/Pages/_get/BagDetails.cshtml.cs +++ b/Monitor/Pages/_get/BagDetails.cshtml.cs @@ -10,6 +10,7 @@ using Core.MarketAnalyzer; namespace Monitor.Pages { public class BagDetailsModel : _Internal.BasePageModelSecure { public ProfitTrailerData PTData = null; + public MiscData MiscData = null; public string DCAMarket = ""; public DCALogData DCALogData = null; public DateTimeOffset DateTimeNow = Constants.confMinDate; @@ -23,13 +24,12 @@ namespace Monitor.Pages { private void BindData() { DCAMarket = GetStringParameter("m", ""); - PTData = this.PtDataObject; - + MiscData = this.PTData.Misc; DCALogData = PTData.DCALog.Find(d => d.Market == DCAMarket); // Convert local offset time to UTC - TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); + TimeSpan offsetTimeSpan = TimeSpan.Parse(MiscData.TimeZoneOffset.Replace("+", "")); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan); } } diff --git a/Monitor/Pages/_get/BagList.cshtml b/Monitor/Pages/_get/BagList.cshtml index 2323bc1..2c072db 100644 --- a/Monitor/Pages/_get/BagList.cshtml +++ b/Monitor/Pages/_get/BagList.cshtml @@ -84,9 +84,9 @@ // Market @if (mps != null && (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)) { - @dcaLogEntry.Market + @dcaLogEntry.Market } else { - @dcaLogEntry.Market + @dcaLogEntry.Market diff --git a/Monitor/Pages/_get/BuyList.cshtml b/Monitor/Pages/_get/BuyList.cshtml index 373d1d0..01b29c9 100644 --- a/Monitor/Pages/_get/BuyList.cshtml +++ b/Monitor/Pages/_get/BuyList.cshtml @@ -37,9 +37,9 @@ string triggerValueText = Core.ProfitTrailer.StrategyHelper.GetTriggerValueText(Model.Summary, buyLogEntry.BuyStrategies, buyLogEntry.BuyStrategy, buyLogEntry.BBTrigger, buyLogEntry.TriggerValue, 0, true); @if (mps != null && (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)) { - @buyLogEntry.Market + @buyLogEntry.Market } else { - @buyLogEntry.Market + @buyLogEntry.Market } @buyLogEntry.PercChange.ToString("#,#0.00")% @if (buyDisabled) { diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 2e09d17..5d1e98e 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -10,7 +10,48 @@ }
-
+ +
+
+
+ @{ + string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")); + if (Model.totalCurrentValue > 100) { + totalCurrentValueString = Math.Round(Model.totalCurrentValue, 2).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")); + } + } +
+
+ TCV: @totalCurrentValueString @Model.Summary.MainMarket +
+
+ + Start: @Model.MiscData.StartBalance +   Gain: @Math.Round(((Model.totalCurrentValue - Model.MiscData.StartBalance) / Model.MiscData.StartBalance) * 100, 2)% + +
+ +
+
+
+ +
+
+

Live TCV Trend + @if (!Model.TotalCurrentValueLiveChartDataJSON.Equals("")) { +
+ +
+ } else { +

Unable to load graph, no sales data found.

+ } +

+
+
+ +
+

Market Trend History

@if (!Model.TrendChartDataJSON.Equals("")) { @@ -23,37 +64,12 @@
-
-
-
- @{ - string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")); - if (Model.totalCurrentValue > 100) { - totalCurrentValueString = Math.Round(Model.totalCurrentValue, 2).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")); - } - } -
-
- - Start:   @Model.MiscData.StartBalance @Model.Summary.MainMarket -     Gain: @Math.Round(((Model.totalCurrentValue - Model.MiscData.StartBalance) / Model.MiscData.StartBalance) * 100, 2)% - -
-
- TCV:   @totalCurrentValueString @Model.Summary.MainMarket -
-
- -
-
-
-
+ -
+
@*
*@
-

Daily Profit +

Daily Profit @if (!Model.ProfitChartDataJSON.Equals("")) {
@@ -70,9 +86,9 @@
@*

*@ -

Live Trends +

Live Market Trends - ANALYZER + ANALYZER

@@ -302,18 +318,23 @@ .labelThreshold(.1) .labelType("percent") .donut(true) - .donutRatio(0.3); + .donutRatio(0.3) + .margin({top: 10, bottom: 10}) + .showLegend(false); // Hide the legend assetDistributionData = @Html.Raw(Model.AssetDistributionData); d3.select("#AssetDistribution svg") + .style('height', '90%') + .style('width', '100%') .datum(assetDistributionData) .transition().duration(0) .call(assetDistributionChart); + - // Add mouseleave, and mousemove event listeners to hide tooltip + // Add mouseleave, and mousemove event listeners to hide tooltip d3.select('.profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').style('opacity', 0); }); d3.select('body').on('mousemove', function() { @@ -455,3 +476,50 @@ $('[data-toggle="tooltip"]').tooltip(); }); + diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs index 6685342..4582728 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs +++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs @@ -26,6 +26,7 @@ namespace Monitor.Pages public DateTimeOffset DateTimeNow = Constants.confMinDate; public string AssetDistributionData = ""; public double totalCurrentValue = 0; + public string TotalCurrentValueLiveChartDataJSON { get; set; } public void OnGet() { // Initialize Config @@ -49,7 +50,7 @@ namespace Monitor.Pages FileHelper.CleanupFilesMinutes(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar, 5); // Convert local offset time to UTC - TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); + TimeSpan offsetTimeSpan = TimeSpan.Parse(MiscData.TimeZoneOffset.Replace("+", "")); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan); // Get last and current active setting @@ -65,8 +66,109 @@ namespace Monitor.Pages BuildMarketTrendChartData(); BuildAssetDistributionData(); BuildProfitChartData(); + StartUpdatingTotalCurrentValueLive(); + UpdateTotalCurrentValueLive(); + BuildTotalCurrentValueLiveChartData(); } + private static System.Timers.Timer timer; + private static List<(DateTime Timestamp, double TotalCurrentValue)> totalCurrentValueLiveList; + +public void StartUpdatingTotalCurrentValueLive() +{ + int liveTCVInterval = PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds; + if (timer != null) + { + // Timer is already running + return; + } + + totalCurrentValueLiveList = new List<(DateTime Timestamp, double TotalCurrentValueLive)>(); + + timer = new System.Timers.Timer(liveTCVInterval * 1000); // Set interval to liveTCVTimer seconds + timer.Elapsed += (sender, e) => UpdateTotalCurrentValueLive(); + timer.Start(); +} + +private void UpdateTotalCurrentValueLive() +{ + double PairsBalance = 0.0; + double DCABalance = 0.0; + double PendingBalance = 0.0; + double AvailableBalance = PTData.GetCurrentBalance(); + bool isSellStrategyTrue = false; + bool isTrailingSellActive = false; + + foreach (DCALogData dcaLogEntry in PTData.DCALog) + { + string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive); + // Aggregate totals + double leverage = dcaLogEntry.Leverage; + if (leverage == 0) + { + leverage = 1; + } + if (sellStrategyText.Contains("PENDING")) + { + PendingBalance = PendingBalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice / leverage); + } + else if (dcaLogEntry.BuyStrategies.Count > 0) + { + DCABalance = DCABalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice / leverage); + } + else + { + PairsBalance = PairsBalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice / leverage); + } + } + double totalCurrentValueLive = PendingBalance + DCABalance + PairsBalance + AvailableBalance; + + // Get the current time + DateTime now = DateTime.UtcNow; + totalCurrentValueLiveList.Add((now, totalCurrentValueLive)); + // Get liveTCVTimeframe from PTMagicConfiguration.GeneralSettings.Monitor + int liveTCVTimeframe = PTMagicConfiguration.GeneralSettings.Monitor.LiveTCVTimeframeMinutes; + + // Calculate the timestamp that is liveTCVTimeframe minutes ago + DateTime threshold = now.AddMinutes(-liveTCVTimeframe); + + // Remove all data points that are older than the threshold + while (totalCurrentValueLiveList.Count > 0 && totalCurrentValueLiveList[0].Item1 < threshold) + { + totalCurrentValueLiveList.RemoveAt(0); + } +} + +private void BuildTotalCurrentValueLiveChartData() +{ + List TotalCurrentValueLivePerIntervalList = new List(); + + if (totalCurrentValueLiveList.Count > 0) + { + foreach (var dataPoint in totalCurrentValueLiveList) + { + DateTime timestamp = dataPoint.Timestamp; + double totalCurrentValueLive = dataPoint.TotalCurrentValue; + + // Convert the timestamp to a Unix timestamp + long unixTimestamp = new DateTimeOffset(timestamp).ToUnixTimeMilliseconds(); + + // Add the data point to the list + TotalCurrentValueLivePerIntervalList.Add(new { x = unixTimestamp, y = totalCurrentValueLive }); + } + + // Convert the list to a JSON string using Newtonsoft.Json + TotalCurrentValueLiveChartDataJSON = Newtonsoft.Json.JsonConvert.SerializeObject(new[] { + new { + key = "Total Current Value", + color = Constants.ChartLineColors[1], + values = TotalCurrentValueLivePerIntervalList + } + }); + } +} + + private void BuildMarketTrendChartData() { List trendChartData = new List(); @@ -95,8 +197,8 @@ namespace Monitor.Pages // Get trend ticks for chart TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { @@ -158,8 +260,8 @@ namespace Monitor.Pages { // Get timezone offset TimeSpan offset; - bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); - string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); + bool isNegative = MiscData.TimeZoneOffset.StartsWith("-"); + string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-'); if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) { diff --git a/Monitor/Pages/_get/DashboardTop.cshtml b/Monitor/Pages/_get/DashboardTop.cshtml index 3a0b262..7d6e98c 100644 --- a/Monitor/Pages/_get/DashboardTop.cshtml +++ b/Monitor/Pages/_get/DashboardTop.cshtml @@ -3,13 +3,15 @@ @{ Layout = null; } - -
+@{ + bool sideBySide = true; + } +
@if (Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxDashboardBuyEntries>0) { -
+
-

Possible Buys (@Model.PTData.BuyLog.Count)more

+

Possible Buys (@Model.PTData.BuyLog.Count)more

@if (Model.PTData.BuyLog.Count == 0) {

Your Profit Trailer did not find anything worth buying so far.

@@ -19,11 +21,10 @@
- - - - - + + + + @@ -57,13 +58,21 @@ @if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { - + } else { - + } - - - + + @if (buyDisabled) { @@ -85,7 +94,7 @@
-

Pairs / DCA / Pending (@Model.PTData.DCALog.Count)more

+

Positions (@Model.PTData.DCALog.Count)more

@if (Model.PTData.DCALog.Count == 0) { @@ -94,16 +103,15 @@ else {
-
Market24HVolumeAskBuy StrategiesMarket Volume Ask Buy Strategies
@buyLogEntry.Market + @buyLogEntry.Market +
@Html.Raw((buyLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) % +
@buyLogEntry.Market   + + @Html.Raw((buyLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) % + @string.Format("{0}%", (buyLogEntry.PercChange * 100).ToString("#,#0.00"))@string.Format("{0}", (buyLogEntry.Volume24h).ToString())@buyLogEntry.CurrentPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@string.Format("{0}", (buyLogEntry.Volume24h).ToString())@buyLogEntry.CurrentPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(buyStrategyText)
+
- - - + + - - - + + + @@ -142,7 +150,6 @@ if (dcaLogEntry.SellStrategies.Count > 0) { isSellStrategyTrue = (dcaLogEntry.SellStrategies.FindAll(ss => !ss.IsTrue).Count == 0); } - string leverage = ""; double leverageValue = 1; string buyStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.BuyStrategies, dcaLogEntry.BuyStrategy, isBuyStrategyTrue, isTrailingBuyActive); @@ -154,55 +161,38 @@ // Profit percentage var profitPercentage = dcaLogEntry.ProfitPercent; - - // if (dcaLogEntry.SellStrategies != null) - // { - // var gainStrategy = dcaLogEntry.SellStrategies.FirstOrDefault(x => x.Name.Contains(" GAIN", StringComparison.InvariantCultureIgnoreCase)); - // if (gainStrategy != null) - // { - // // Use the gain percentage value as it is accurate to what can be achieved with the order book! - // profitPercentage = gainStrategy.CurrentValue; - // } - // } // Render the row - - if (!sellStrategyText.Contains("PENDING-BUY")) + if (!sellStrategyText.Contains("PENDING-BUY")) { - - - - - - + @@ -234,7 +224,7 @@ double TargetGain = leverageValue * dcaLogEntry.TargetGainValue.Value; } else @@ -242,7 +232,7 @@ } @@ -255,24 +245,22 @@ } - - { - // Aggregate totals - double bagGain = (profitPercentage / 100) * dcaLogEntry.TotalCost; - Model.TotalBagCost = Model.TotalBagCost + dcaLogEntry.TotalCost; - Model.TotalBagGain = Model.TotalBagGain + bagGain; - } - + + { + // Aggregate totals + double bagGain = (profitPercentage / 100) * dcaLogEntry.TotalCost; + Model.TotalBagCost = Model.TotalBagCost + dcaLogEntry.TotalCost; + Model.TotalBagGain = Model.TotalBagGain + bagGain; + } } - - } - - - - - - - + } + + + + + + +
Market24HCostMarket Cost DCASellProfitDCA Sell Profit
@if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { - @dcaLogEntry.Market + @dcaLogEntry.Market } else { - @dcaLogEntry.Market   - + @dcaLogEntry.Market   } -
- @bagAgeText +
@Html.Raw((dcaLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) % +
@Html.Raw((dcaLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))% @Html.Raw(dcaLogEntry.TotalCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))@Html.Raw(dcaLogEntry.TotalCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))
@bagAgeText
@if (dcaEnabled) { - @if (dcaLogEntry.BoughtTimes > 0) + if (dcaLogEntry.BoughtTimes > 0) { @dcaLogEntry.BoughtTimes; } } else { - + } @TargetGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
-
@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
+
@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %
None

-
@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
+
@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %
Totals:@Html.Raw(Model.TotalBagCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))@Html.Raw((((Model.TotalBagGain) / Model.TotalBagCost) * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))%Totals:@Html.Raw(Model.TotalBagCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))@Html.Raw((((Model.TotalBagGain) / Model.TotalBagCost) * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) %
diff --git a/Monitor/Pages/_get/DashboardTop.cshtml.cs b/Monitor/Pages/_get/DashboardTop.cshtml.cs index 0efd6e9..8bc48cf 100644 --- a/Monitor/Pages/_get/DashboardTop.cshtml.cs +++ b/Monitor/Pages/_get/DashboardTop.cshtml.cs @@ -1,15 +1,16 @@ using System; using Core.Main; using Core.Main.DataObjects; +using Core.Main.DataObjects.PTMagicData; namespace Monitor.Pages { public class DashboardTopModel : _Internal.BasePageModelSecureAJAX { public ProfitTrailerData PTData = null; + public MiscData MiscData = null; public DateTimeOffset DateTimeNow = Constants.confMinDate; public void OnGet() { // Initialize Config base.Init(); - BindData(); } public double TotalBagCost = 0; @@ -17,9 +18,9 @@ namespace Monitor.Pages { public double TotalBagGain = 0; private void BindData() { PTData = this.PtDataObject; - + MiscData = this.PTData.Misc; // Convert local offset time to UTC - TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); + TimeSpan offsetTimeSpan = TimeSpan.Parse(MiscData.TimeZoneOffset.Replace("+", "")); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan); } } diff --git a/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json b/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json index 650c85b..275391f 100644 --- a/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json +++ b/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json @@ -10,7 +10,7 @@ "ProfitTrailerMonitorURLXtra": "", // URLs for additional bots you want PTM to update (optional - comma separated list) "ProfitTrailerDefaultSettingName": "default", // Your Profit Trailer default setting name (needed to change your settings) "Exchange": "Bittrex", // The exchange your are running Profit Trailer on - "TimezoneOffset": "+0:00", // Your timezone offset from UTC time + //"TimezoneOffset": "+0:00", // Your timezone offset from UTC time "FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute "InstanceName": "PT Magic", // The name of the instance of this bot. This will be used in your monitor and your Telegram messages. In case you are running more than one bot, you may set different names to separate them //"FreeCurrencyConverterAPIKey": "" // If "MainFiatCurrency" above is anything other than USD, you must obtain an API key from https://free.currencyconverterapi.com/free-api-key diff --git a/_Development/DevSettings/settings.general.json b/_Development/DevSettings/settings.general.json index 9b8e822..797ebff 100644 --- a/_Development/DevSettings/settings.general.json +++ b/_Development/DevSettings/settings.general.json @@ -10,7 +10,7 @@ "ProfitTrailerMonitorURLXtra": "", // URLs for additional bots you want PTM to update (optional - comma separated list) "ProfitTrailerDefaultSettingName": "default", // Your Profit Trailer default setting name (needed to change your settings) "Exchange": "Bittrex", // The exchange your are running Profit Trailer on - "TimezoneOffset": "+0:00", // Your timezone offset from UTC time + //"TimezoneOffset": "+0:00", // Your timezone offset from UTC time "FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute "InstanceName": "PT Magic", // The name of the instance of this bot. This will be used in your monitor and your Telegram messages. In case you are running more than one bot, you may set different names to separate them "CoinMarketCapAPIKey": "", //CoinMarketCap Api From 1669534044ed23cf1e2c09ea049d3b1a2b66f88c Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Sun, 28 Jan 2024 02:39:47 +0900 Subject: [PATCH 02/19] SMS full reset & Analyzer indicator --- Core/Main/PTMagic.cs | 21 +++++++ Monitor/Pages/Index.cshtml | 14 +++-- Monitor/Pages/ManageSMS.cshtml | 68 +++++++++++++++++++++- Monitor/Pages/ManageSMS.cshtml.cs | 41 ++++++++++++- Monitor/Pages/SettingsGeneral.cshtml | 12 ++-- Monitor/Pages/_Layout.cshtml | 2 +- Monitor/Pages/_get/DashboardTop.cshtml | 2 +- Monitor/Pages/_get/TickerWidgets.cshtml | 3 + Monitor/Pages/_get/TickerWidgets.cshtml.cs | 36 +++++++++++- 9 files changed, 181 insertions(+), 18 deletions(-) diff --git a/Core/Main/PTMagic.cs b/Core/Main/PTMagic.cs index 1270cd0..7ed366f 100644 --- a/Core/Main/PTMagic.cs +++ b/Core/Main/PTMagic.cs @@ -59,6 +59,7 @@ namespace Core.Main private Dictionary _singleMarketSettingsCount = new Dictionary(); Dictionary> _triggeredSingleMarketSettings = new Dictionary>(); private static volatile object _lockObj = new object(); + private Mutex mutex = new Mutex(false, "analyzerStateMutex"); public LogHelper Log { @@ -122,6 +123,22 @@ namespace Core.Main _state = value; } } + public void WriteStateToFile() + { + try + { + mutex.WaitOne(); // Acquire the mutex + + string filePath = "_data/AnalyzerState."; + File.WriteAllText(filePath, this.State.ToString()); + + } + finally + { + mutex.ReleaseMutex(); // Release the mutex even if exceptions occur + } + } + public int RunCount { @@ -840,6 +857,7 @@ namespace Core.Main { // Change state to "Running" this.State = Constants.PTMagicBotState_Running; + this.WriteStateToFile(); this.RunCount++; this.LastRuntime = DateTime.UtcNow; @@ -975,6 +993,7 @@ namespace Core.Main // Change state to Finished / Stopped this.State = Constants.PTMagicBotState_Idle; + this.WriteStateToFile(); } } } @@ -991,6 +1010,7 @@ namespace Core.Main { Log.DoLogWarn("PTMagic raid " + this.RunCount.ToString() + " is taking longer than expected. Consider increasing your IntervalMinues setting, reducing other processes on your PC, or raising PTMagic's priority."); this.State = Constants.PTMagicBotState_Idle; + this.WriteStateToFile(); Log.DoLogInfo("PTMagic status reset, waiting for the next raid to be good to go again."); } } @@ -998,6 +1018,7 @@ namespace Core.Main { Log.DoLogWarn("No LastRuntimeSummary.json found after raid " + this.RunCount.ToString() + ", trying to reset PT Magic status..."); this.State = Constants.PTMagicBotState_Idle; + this.WriteStateToFile(); Log.DoLogInfo("PTMagic status reset, waiting for the next raid to be good to go again."); } } diff --git a/Monitor/Pages/Index.cshtml b/Monitor/Pages/Index.cshtml index 25b691c..901f19f 100644 --- a/Monitor/Pages/Index.cshtml +++ b/Monitor/Pages/Index.cshtml @@ -25,7 +25,8 @@ + } diff --git a/Monitor/Pages/SalesAnalyzer.cshtml b/Monitor/Pages/SalesAnalyzer.cshtml index a3cb551..2d341a3 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml +++ b/Monitor/Pages/SalesAnalyzer.cshtml @@ -396,7 +396,7 @@ // Add mouseleave, and mousemove event listeners to hide tooltip d3.select('.sales-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); }); d3.select('body').on('mousemove', function() { @@ -405,7 +405,7 @@ var mouseY = d3.event.clientY; if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); } }); nv.utils.windowResize(salesChart.update); @@ -444,7 +444,7 @@ // Add mouseleave, and mousemove event listeners to hide tooltip d3.select('.cumulative-profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); }); d3.select('body').on('mousemove', function() { @@ -453,7 +453,7 @@ var mouseY = d3.event.clientY; if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); } }); nv.utils.windowResize(cumulativeProfitChart.update); @@ -490,9 +490,9 @@ .transition().duration(0) .call(TCVChart); - // Add mouseleave, and mousemove event listeners to hide tooltip + // Add mouseleave, and mousemove event listeners to hide tooltip d3.select('.TCV-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); }); d3.select('body').on('mousemove', function() { @@ -501,7 +501,7 @@ var mouseY = d3.event.clientY; if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); } }); nv.utils.windowResize(TCVChart.update); @@ -538,9 +538,32 @@ .transition().duration(0) .call(profitChart); - // Add mouseleave, and mousemove event listeners to hide tooltip + + profitChart.dispatch.on('renderEnd', function() { + // Get the chart's container + var container = d3.select('.profit-chart .nv-wrap.nv-lineChart .nv-linesWrap'); + + // Check if profitData[0].values is not empty + if (profitData[0].values.length > 0) { + // Get the x-values of the first and last data points + var xMin = profitChart.xAxis.scale()(profitData[0].values[0].x); + var xMax = profitChart.xAxis.scale()(profitData[0].values[profitData[0].values.length - 1].x); + + // Add a line at y=0 + container.insert('line', ':first-child') + .attr('x1', xMin) // x position of the first end of the line + .attr('y1', profitChart.yAxis.scale()(0)) // y position of the first end of the line + .attr('x2', xMax) // x position of the second end of the line + .attr('y2', profitChart.yAxis.scale()(0)) // y position of the second end of the line + .attr('stroke', 'gray') // color of the line + .attr('stroke-width', 2); // width of the line + } + }); + + + // Add mouseleave, and mousemove event listeners to hide tooltip d3.select('.profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); }); d3.select('body').on('mousemove', function() { @@ -549,7 +572,7 @@ var mouseY = d3.event.clientY; if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); + d3.select('.nvtooltip').remove(); } }); nv.utils.windowResize(profitChart.update); diff --git a/Monitor/Pages/SettingsGeneral.cshtml.cs b/Monitor/Pages/SettingsGeneral.cshtml.cs index a731e9b..e601e69 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml.cs +++ b/Monitor/Pages/SettingsGeneral.cshtml.cs @@ -48,18 +48,12 @@ namespace Monitor.Pages // Read the new settings PTMagicConfiguration.GeneralSettings.Application.IsEnabled = HttpContext.Request.Form["Application_IsEnabled"].Equals("on"); - 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.AnalyzerChart = HttpContext.Request.Form["Monitor_AnalyzerChart"]; diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 5d1e98e..3a972d2 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -21,7 +21,7 @@ totalCurrentValueString = Math.Round(Model.totalCurrentValue, 2).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")); } } -
+
TCV: @totalCurrentValueString @Model.Summary.MainMarket
@@ -96,7 +96,7 @@ Name Markets Timeframe - Threshold   + Threshold   Change @@ -324,28 +324,13 @@ assetDistributionData = @Html.Raw(Model.AssetDistributionData); - d3.select("#AssetDistribution svg") + d3.select(".asset-distribution svg") // Change this line .style('height', '90%') .style('width', '100%') .datum(assetDistributionData) .transition().duration(0) .call(assetDistributionChart); - - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); - }); - - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.profit-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; - - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); - } - }); nv.utils.windowResize(assetDistributionChart.update); return assetDistributionChart; }); @@ -375,24 +360,34 @@ trendData = @Html.Raw(Model.TrendChartDataJSON); - d3.select('.trend-chart svg') + var svg = d3.select('.trend-chart svg').node(); + d3.select(svg) .datum(trendData) .transition().duration(0) .call(trendChart); - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); + + trendChart.dispatch.on('renderEnd', function() { + // Get the chart's container + var container = d3.select('.trend-chart .nv-wrap.nv-lineChart .nv-linesWrap'); + + // Get the x-values of the first and last data points + var xRange = trendChart.xAxis.scale().range(); + var xMin = xRange[0]; + var xMax = xRange[1]; + + + // Add a line at y=0 + container.insert('line', ':first-child') + .attr('x1', xMin) // x position of the first end of the line + .attr('y1', trendChart.yAxis.scale()(0)) // y position of the first end of the line + .attr('x2', xMax) // x position of the second end of the line + .attr('y2', trendChart.yAxis.scale()(0)) // y position of the second end of the line + .attr('stroke', 'gray') // color of the line + .attr('stroke-width', 2); // width of the line }); - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.profit-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; + - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); - } - }); nv.utils.windowResize(trendChart.update); return trendChart; }); @@ -427,20 +422,27 @@ .transition().duration(0) .call(profitChart); - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').style('opacity', 0); - }); + profitChart.dispatch.on('renderEnd', function() { + // Get the chart's container + var container = d3.select('.profit-chart .nv-wrap.nv-lineChart .nv-linesWrap'); - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.profit-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; + // Check if profitData[0].values is not empty + if (profitData[0].values.length > 0) { + // Get the x-values of the first and last data points + var xMin = profitChart.xAxis.scale()(profitData[0].values[0].x); + var xMax = profitChart.xAxis.scale()(profitData[0].values[profitData[0].values.length - 1].x); - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').style('opacity', 0); - } + // Add a line at y=0 + container.insert('line', ':first-child') + .attr('x1', xMin) // x position of the first end of the line + .attr('y1', profitChart.yAxis.scale()(0)) // y position of the first end of the line + .attr('x2', xMax) // x position of the second end of the line + .attr('y2', profitChart.yAxis.scale()(0)) // y position of the second end of the line + .attr('stroke', 'gray') // color of the line + .attr('stroke-width', 2); // width of the line + } }); + nv.utils.windowResize(profitChart.update); return profitChart; }); @@ -451,31 +453,10 @@ + + + diff --git a/Monitor/Pages/_get/SettingsMarketTrends.cshtml b/Monitor/Pages/_get/SettingsMarketTrends.cshtml index a4611bf..f32ef9f 100644 --- a/Monitor/Pages/_get/SettingsMarketTrends.cshtml +++ b/Monitor/Pages/_get/SettingsMarketTrends.cshtml @@ -78,7 +78,7 @@
- +
Leave empty to exclude none diff --git a/PTMagic/_defaults/_default_settings_PT_2.x/settings.analyzer.json b/PTMagic/_defaults/_default_settings_PT_2.x/settings.analyzer.json index 33ed9ac..764781b 100644 --- a/PTMagic/_defaults/_default_settings_PT_2.x/settings.analyzer.json +++ b/PTMagic/_defaults/_default_settings_PT_2.x/settings.analyzer.json @@ -22,7 +22,8 @@ "TrendCurrency": "Market", // Trend Currency to build the trend against. If set to "Fiat", the trend will // take the USD value of your main currency into account to build the trend. // "Market" will build a trend against your base currency, such as BTC or USDT. - "TrendThreshold": 15, // Any coin that is above 15% or below -15% for this timeframe will not be used when calculating the market average. + "TrendThreshold": 15, // Any coin that is above 15% or below -15% for this timeframe will be considered an outlier, + // and not used when calculating the market average. "DisplayGraph": false, // Use this trend in the graph on the PTM Monitor dashboard and market analyzer "DisplayOnMarketAnalyzerList": false // Disply this trend for all coins on the PTM Monitor market analyzer }, diff --git a/_Development/DevSettings/settings.analyzer.json b/_Development/DevSettings/settings.analyzer.json index 33ed9ac..753d4fb 100644 --- a/_Development/DevSettings/settings.analyzer.json +++ b/_Development/DevSettings/settings.analyzer.json @@ -22,7 +22,8 @@ "TrendCurrency": "Market", // Trend Currency to build the trend against. If set to "Fiat", the trend will // take the USD value of your main currency into account to build the trend. // "Market" will build a trend against your base currency, such as BTC or USDT. - "TrendThreshold": 15, // Any coin that is above 15% or below -15% for this timeframe will not be used when calculating the market average. + "TrendThreshold": 15, // Any coin that is above 15% or below -15% for this timeframe will be considered an outlier, + // and not used when calculating the market average. "DisplayGraph": false, // Use this trend in the graph on the PTM Monitor dashboard and market analyzer "DisplayOnMarketAnalyzerList": false // Disply this trend for all coins on the PTM Monitor market analyzer }, From 853520d3b037c1094af92a90da4be01f89e19bba Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:48:36 +0900 Subject: [PATCH 06/19] sales analyzer tooltips --- Monitor/Pages/SalesAnalyzer.cshtml | 88 +++++++++-------------- Monitor/Pages/_get/DashboardBottom.cshtml | 51 +++++++------ 2 files changed, 56 insertions(+), 83 deletions(-) diff --git a/Monitor/Pages/SalesAnalyzer.cshtml b/Monitor/Pages/SalesAnalyzer.cshtml index 2d341a3..84a0393 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml +++ b/Monitor/Pages/SalesAnalyzer.cshtml @@ -394,20 +394,7 @@ .transition().duration(0) .call(salesChart); - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.sales-chart').on('mouseleave', function() { - d3.select('.nvtooltip').remove(); - }); - - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.sales-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; - - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').remove(); - } - }); + nv.utils.windowResize(salesChart.update); return salesChart; }); @@ -442,20 +429,7 @@ .transition().duration(0) .call(cumulativeProfitChart); - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.cumulative-profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').remove(); - }); - - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.cumulative-profit-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; - - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').remove(); - } - }); + nv.utils.windowResize(cumulativeProfitChart.update); return cumulativeProfitChart; }); @@ -490,20 +464,6 @@ .transition().duration(0) .call(TCVChart); - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.TCV-chart').on('mouseleave', function() { - d3.select('.nvtooltip').remove(); - }); - - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.TCV-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; - - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').remove(); - } - }); nv.utils.windowResize(TCVChart.update); return TCVChart; }); @@ -561,20 +521,6 @@ }); - // Add mouseleave, and mousemove event listeners to hide tooltip - d3.select('.profit-chart').on('mouseleave', function() { - d3.select('.nvtooltip').remove(); - }); - - d3.select('body').on('mousemove', function() { - var chartBounds = d3.select('.profit-chart')[0][0].getBoundingClientRect(); - var mouseX = d3.event.clientX; - var mouseY = d3.event.clientY; - - if (mouseX < chartBounds.left || mouseX > chartBounds.right || mouseY < chartBounds.top || mouseY > chartBounds.bottom) { - d3.select('.nvtooltip').remove(); - } - }); nv.utils.windowResize(profitChart.update); return profitChart; }); @@ -582,4 +528,34 @@ } })(jQuery); + + + } diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 3a972d2..1e6f386 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -493,33 +493,30 @@ From 7dcf8d38c814b4d4ee98a178a979e0fd01e47be7 Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Wed, 31 Jan 2024 00:45:34 +0900 Subject: [PATCH 07/19] Analyzer Trigger Connection --- Core/DataObjects/PTMagicData.cs | 2 -- Monitor/Pages/_get/SettingsGlobalSettings.cshtml | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index 9aff623..27fe0fd 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -166,8 +166,6 @@ namespace Core.Main.DataObjects.PTMagicData public class SingleMarketSetting { public string SettingName { get; set; } - - public string TriggerLogic { get; set; } = "AND"; public string TriggerConnection { get; set; } = "AND"; diff --git a/Monitor/Pages/_get/SettingsGlobalSettings.cshtml b/Monitor/Pages/_get/SettingsGlobalSettings.cshtml index f7f6cfc..cc98576 100644 --- a/Monitor/Pages/_get/SettingsGlobalSettings.cshtml +++ b/Monitor/Pages/_get/SettingsGlobalSettings.cshtml @@ -36,12 +36,7 @@ @if (!Model.GlobalSetting.SettingName.StartsWith("Default", StringComparison.InvariantCultureIgnoreCase)) {
-
- -
+

From 78e7e18631cbb1ef4fd7b2ecb846bc60f2ddc456 Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Wed, 31 Jan 2024 04:55:16 +0900 Subject: [PATCH 08/19] Reset All SMS and Tag bug fixes --- Core/DataObjects/PTMagicData.cs | 1 - Core/Main/PTMagic.cs | 6 +-- Monitor/Pages/ManageSMS.cshtml | 79 ++++++++++++++++++++----------- Monitor/Pages/ManageSMS.cshtml.cs | 1 - 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index 27fe0fd..245199a 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -156,7 +156,6 @@ namespace Core.Main.DataObjects.PTMagicData { public string SettingName { get; set; } public string TriggerConnection { get; set; } = "AND"; - public string TriggerLogic { get; set; } = ""; public List Triggers { get; set; } = new List(); public Dictionary PairsProperties { get; set; } = new Dictionary(); public Dictionary DCAProperties { get; set; } = new Dictionary(); diff --git a/Core/Main/PTMagic.cs b/Core/Main/PTMagic.cs index 28b5b56..c9103d4 100644 --- a/Core/Main/PTMagic.cs +++ b/Core/Main/PTMagic.cs @@ -1408,15 +1408,15 @@ namespace Core.Main else { // New logic - string triggerLogic = globalSetting.TriggerConnection; + string triggerConnection = globalSetting.TriggerConnection; foreach (var triggerResult in triggerResults) { - triggerLogic = triggerLogic.Replace(triggerResult.Key, triggerResult.Value.ToString().ToLower()); + triggerConnection = triggerConnection.Replace(triggerResult.Key, triggerResult.Value.ToString().ToLower()); } try { - bool settingTriggered = (bool)System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(System.Linq.Dynamic.Core.ParsingConfig.Default, new ParameterExpression[0], typeof(bool), triggerLogic).Compile().DynamicInvoke(); + bool settingTriggered = (bool)System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(System.Linq.Dynamic.Core.ParsingConfig.Default, new ParameterExpression[0], typeof(bool), triggerConnection).Compile().DynamicInvoke(); // Setting got triggered -> Activate it! if (settingTriggered) diff --git a/Monitor/Pages/ManageSMS.cshtml b/Monitor/Pages/ManageSMS.cshtml index f854257..1cd038e 100644 --- a/Monitor/Pages/ManageSMS.cshtml +++ b/Monitor/Pages/ManageSMS.cshtml @@ -30,7 +30,7 @@ @sms: @smsCount     } @if (Model.PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected) { - Reset ALL Single MarketSettings + Reset ALL Single MarketSettings } else { Delete File } @@ -202,7 +202,7 @@
@@ -236,41 +236,64 @@ @section Scripts { diff --git a/Monitor/Pages/ManageSMS.cshtml.cs b/Monitor/Pages/ManageSMS.cshtml.cs index cf142a7..60d3bb3 100644 --- a/Monitor/Pages/ManageSMS.cshtml.cs +++ b/Monitor/Pages/ManageSMS.cshtml.cs @@ -46,7 +46,6 @@ namespace Monitor.Pages string webRootParent = Directory.GetParent(_hostingEnvironment.WebRootPath).FullName; string ptMagicRoot = Directory.GetParent(webRootParent).FullName; string analyzerStatePath = Path.Combine(ptMagicRoot, "_data", "AnalyzerState"); - Console.WriteLine("analyzerStatePath: " + analyzerStatePath); // Read the AnalyzerState file if (System.IO.File.Exists(analyzerStatePath)) From 4f9b76bcea5c72771dd016bd92884e0f7988fb1d Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:25:04 +0900 Subject: [PATCH 09/19] bug fixes --- Monitor/Pages/Index.cshtml | 32 +++++++---- Monitor/Pages/MarketAnalyzer.cshtml | 4 ++ Monitor/Pages/SalesAnalyzer.cshtml | 4 ++ Monitor/Pages/_get/DashboardBottom.cshtml | 69 +++++++++++++++-------- PTMagic/Program.cs | 2 +- 5 files changed, 74 insertions(+), 37 deletions(-) diff --git a/Monitor/Pages/Index.cshtml b/Monitor/Pages/Index.cshtml index 901f19f..08f3ac9 100644 --- a/Monitor/Pages/Index.cshtml +++ b/Monitor/Pages/Index.cshtml @@ -30,6 +30,8 @@ var intervalDashboardTop; var intervalDashboardBottom; + + var loadDashboardTop = function () { $("#baglist-refresh-icon").html(''); $("#buylist-refresh-icon").html(''); @@ -68,6 +70,23 @@ if (intervalDashboardBottom != null) { clearInterval(intervalDashboardBottom); } + console.log(counterIndex["DashboardBottom"]); + + // Destroy all d3 svg graph to avoid memory leak every 10 refreshes of Dashboard Bottom + if (counterIndex["DashboardBottom"] >= 10) { + $(".nvtooltip").remove(); + $("svg > *").remove(); + $("svg").remove(); + $("svg").off(); // Remove all event listeners from SVG elements + nv.charts = {}; + nv.graphs = []; + nv.logs = {}; + nv.tooltip = {}; + window.cleanupData(); + // Reset the counter + counterIndex["DashboardBottom"] = 0; + console.log("d3 svg graph destroyed"); + } // Load dashboard $("#dashboardBottom").load('@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)_get/DashboardBottom', '', function (responseText, textStatus, XMLHttpRequest) { @@ -84,18 +103,7 @@ // Increment the counter counterIndex["DashboardBottom"] = (counterIndex["DashboardBottom"] || 0) + 1; - // Destroy all d3 svg graph to avoid memory leak every 30 refreshes of Dashboard Bottom - if (counterIndex["DashboardBottom"] >= 30) { - $(".nvtooltip").remove(); - $("svg > *").remove(); - $("svg").remove(); - nv.charts = {}; - nv.graphs = []; - nv.logs = {}; - nv.tooltip = {}; - // Reset the counter - counterIndex["DashboardBottom"] = 0; - } + } // Reinstate the interval. diff --git a/Monitor/Pages/MarketAnalyzer.cshtml b/Monitor/Pages/MarketAnalyzer.cshtml index 562c717..380d127 100644 --- a/Monitor/Pages/MarketAnalyzer.cshtml +++ b/Monitor/Pages/MarketAnalyzer.cshtml @@ -404,6 +404,9 @@ else // Get the chart's container var container = d3.select('.trend-chart .nv-wrap.nv-lineChart .nv-linesWrap'); + // Remove any existing y=0 line + container.selectAll('.zero-line').remove(); + // Get the x-values of the first and last data points var xRange = lineChart.xAxis.scale().range(); var xMin = xRange[0]; @@ -412,6 +415,7 @@ else // Add a line at y=0 container.insert('line', ':first-child') + .attr('class', 'zero-line') // Add a class to the line for easy .attr('x1', xMin) // x position of the first end of the line .attr('y1', lineChart.yAxis.scale()(0)) // y position of the first end of the line .attr('x2', xMax) // x position of the second end of the line diff --git a/Monitor/Pages/SalesAnalyzer.cshtml b/Monitor/Pages/SalesAnalyzer.cshtml index 84a0393..29554b6 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml +++ b/Monitor/Pages/SalesAnalyzer.cshtml @@ -503,6 +503,9 @@ // Get the chart's container var container = d3.select('.profit-chart .nv-wrap.nv-lineChart .nv-linesWrap'); + // Remove any existing y=0 line + container.selectAll('.zero-line').remove(); + // Check if profitData[0].values is not empty if (profitData[0].values.length > 0) { // Get the x-values of the first and last data points @@ -511,6 +514,7 @@ // Add a line at y=0 container.insert('line', ':first-child') + .attr('class', 'zero-line') // Add a class to the line for easy selection .attr('x1', xMin) // x position of the first end of the line .attr('y1', profitChart.yAxis.scale()(0)) // y position of the first end of the line .attr('x2', xMax) // x position of the second end of the line diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 1e6f386..0a7f8ca 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -299,13 +299,20 @@ + + + + - - + + diff --git a/PTMagic/Program.cs b/PTMagic/Program.cs index ca7ee6a..288dfaf 100644 --- a/PTMagic/Program.cs +++ b/PTMagic/Program.cs @@ -6,7 +6,7 @@ using Core.Helper; using Microsoft.Extensions.DependencyInjection; -[assembly: AssemblyVersion("2.7.1")] +[assembly: AssemblyVersion("2.7.2")] [assembly: AssemblyProduct("PT Magic")] namespace PTMagic From 6d849c8c030427179abf55a0e424595607230285 Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Sat, 3 Feb 2024 00:38:06 +0900 Subject: [PATCH 10/19] Version number = 2.8.1 --- PTMagic/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PTMagic/Program.cs b/PTMagic/Program.cs index 288dfaf..919933d 100644 --- a/PTMagic/Program.cs +++ b/PTMagic/Program.cs @@ -6,7 +6,7 @@ using Core.Helper; using Microsoft.Extensions.DependencyInjection; -[assembly: AssemblyVersion("2.7.2")] +[assembly: AssemblyVersion("2.8.1")] [assembly: AssemblyProduct("PT Magic")] namespace PTMagic From f8573661c9325d34ec7a24601ea8e693a6fc22f1 Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Sat, 3 Feb 2024 02:22:39 +0900 Subject: [PATCH 11/19] Monitor DashboardRefreshSeconds --- Core/DataObjects/PTMagicData.cs | 2 +- Core/DataObjects/ProfitTrailerData.cs | 16 ++++---- Monitor/Pages/Index.cshtml | 2 +- Monitor/Pages/SettingsGeneral.cshtml | 2 +- Monitor/Pages/SettingsGeneral.cshtml.cs | 2 +- Monitor/Pages/_get/DashboardBottom.cshtml | 6 +-- Monitor/Pages/_get/DashboardBottom.cshtml.cs | 2 +- Monitor/Pages/_get/TickerWidgets.cshtml.cs | 40 ++++++++++--------- .../settings.general.json | 2 +- .../DevSettings/settings.general.json | 2 +- 10 files changed, 40 insertions(+), 36 deletions(-) diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index 245199a..3b1a668 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -59,7 +59,7 @@ namespace Core.Main.DataObjects.PTMagicData public int GraphIntervalMinutes { get; set; } = 60; public int GraphMaxTimeframeHours { get; set; } = 24; public int ProfitsMaxTimeframeDays { get; set; } = 60; - public int RefreshSeconds { get; set; } = 30; + public int DashboardChartsRefreshSeconds { get; set; } = 30; public int BagAnalyzerRefreshSeconds { get; set; } = 5; public int BuyAnalyzerRefreshSeconds { get; set; } = 5; public int MaxTopMarkets { get; set; } = 20; diff --git a/Core/DataObjects/ProfitTrailerData.cs b/Core/DataObjects/ProfitTrailerData.cs index 13c2050..c4008b1 100644 --- a/Core/DataObjects/ProfitTrailerData.cs +++ b/Core/DataObjects/ProfitTrailerData.cs @@ -114,7 +114,7 @@ namespace Core.Main.DataObjects if (_misc == null || (DateTime.UtcNow > _miscRefresh)) { _misc = BuildMiscData(GetDataFromProfitTrailer("api/v2/data/misc")); - _miscRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _miscRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } @@ -185,7 +185,7 @@ namespace Core.Main.DataObjects { JArray dailyStatsSection = (JArray)extraSection["dailyStats"]; _dailyStats = dailyStatsSection.Select(j => BuildDailyStatsData(j as JObject)).ToList(); - _dailyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _dailyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } @@ -220,7 +220,7 @@ namespace Core.Main.DataObjects if (_properties == null || (DateTime.UtcNow > _propertiesRefresh)) { _properties = BuildProptertiesData(GetDataFromProfitTrailer("api/v2/data/properties")); - _propertiesRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _propertiesRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } @@ -263,7 +263,7 @@ namespace Core.Main.DataObjects jsonReader.Read(); // Move to the value of the "basic" property JObject basicSection = JObject.Load(jsonReader); _stats = BuildStatsData(basicSection); - _statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); break; } } @@ -360,7 +360,7 @@ namespace Core.Main.DataObjects { JArray dailyPNLSection = (JArray)extraSection["dailyPNLStats"]; _dailyPNL = dailyPNLSection.Select(j => BuildDailyPNLData(j as JObject)).ToList(); - _dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } @@ -434,7 +434,7 @@ namespace Core.Main.DataObjects _profitablePairs.Add(BuildProfitablePairs(profitablePair)); counter++; } - _profitablePairsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _profitablePairsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } @@ -500,7 +500,7 @@ namespace Core.Main.DataObjects { JArray dailyTCVSection = (JArray)extraSection["dailyTCVStats"]; _dailyTCV = dailyTCVSection.Select(j => BuildDailyTCVData(j as JObject)).ToList(); - _dailyTCVRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _dailyTCVRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } @@ -568,7 +568,7 @@ namespace Core.Main.DataObjects { JArray monthlyStatsSection = (JArray)extraSection["monthlyStats"]; _monthlyStats = monthlyStatsSection.Select(j => BuildMonthlyStatsData(j as JObject)).ToList(); - _monthlyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + _monthlyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds - 1); } } } diff --git a/Monitor/Pages/Index.cshtml b/Monitor/Pages/Index.cshtml index 08f3ac9..2ff2ffe 100644 --- a/Monitor/Pages/Index.cshtml +++ b/Monitor/Pages/Index.cshtml @@ -107,7 +107,7 @@ } // Reinstate the interval. - intervalDashboardBottom = setInterval(function () { loadDashboardBottom(); }, @Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000); + intervalDashboardBottom = setInterval(function () { loadDashboardBottom(); }, @Model.PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds * 1000); }); }; diff --git a/Monitor/Pages/SettingsGeneral.cshtml b/Monitor/Pages/SettingsGeneral.cshtml index 0918b6f..f01ef9b 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml +++ b/Monitor/Pages/SettingsGeneral.cshtml @@ -225,7 +225,7 @@
- +
diff --git a/Monitor/Pages/SettingsGeneral.cshtml.cs b/Monitor/Pages/SettingsGeneral.cshtml.cs index e601e69..83f297f 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml.cs +++ b/Monitor/Pages/SettingsGeneral.cshtml.cs @@ -62,7 +62,7 @@ namespace Monitor.Pages 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.ProfitsMaxTimeframeDays = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_ProfitsMaxTimeframeDays"], PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays); - PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_RefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds); + PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_RefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds); PTMagicConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_BagAnalyzerRefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds); PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_BuyAnalyzerRefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds); PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform = HttpContext.Request.Form["Monitor_LinkPlatform"]; diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 0a7f8ca..6b66682 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -13,8 +13,8 @@
-
+
@{ string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")); if (Model.totalCurrentValue > 100) { @@ -87,7 +87,7 @@ @*

*@

Live Market Trends - + ANALYZER

diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs index 4582728..8fdb9b0 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs +++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs @@ -75,7 +75,7 @@ namespace Monitor.Pages public void StartUpdatingTotalCurrentValueLive() { - int liveTCVInterval = PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds; + int liveTCVInterval = PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds; if (timer != null) { // Timer is already running diff --git a/Monitor/Pages/_get/TickerWidgets.cshtml.cs b/Monitor/Pages/_get/TickerWidgets.cshtml.cs index 4d16b0a..b11d08a 100644 --- a/Monitor/Pages/_get/TickerWidgets.cshtml.cs +++ b/Monitor/Pages/_get/TickerWidgets.cshtml.cs @@ -27,26 +27,30 @@ namespace Monitor.Pages { } public bool IsAnalyzerRunning() { - // Acquire the mutex before accessing the file - try - { - mutex.WaitOne(0); - - string webRootParent = Directory.GetParent(_hostingEnvironment.WebRootPath).FullName; - string ptMagicRoot = Directory.GetParent(webRootParent).FullName; - string analyzerStatePath = Path.Combine(ptMagicRoot, "_data", "AnalyzerState"); - if (System.IO.File.Exists(analyzerStatePath)) + bool ownsMutex = false; + try { - string state = System.IO.File.ReadAllText(analyzerStatePath); - return state == "1"; - } - return false; + // Try to acquire the mutex. + ownsMutex = mutex.WaitOne(0); - } - finally - { - mutex.ReleaseMutex(); // Always release the mutex - } + string webRootParent = Directory.GetParent(_hostingEnvironment.WebRootPath).FullName; + string ptMagicRoot = Directory.GetParent(webRootParent).FullName; + string analyzerStatePath = Path.Combine(ptMagicRoot, "_data", "AnalyzerState"); + if (System.IO.File.Exists(analyzerStatePath)) + { + string state = System.IO.File.ReadAllText(analyzerStatePath); + return state == "1"; + } + return false; + } + finally + { + // Only release the mutex if this thread owns it. + if (ownsMutex) + { + mutex.ReleaseMutex(); + } + } } private void BindData() { diff --git a/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json b/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json index 103d21d..3e13de7 100644 --- a/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json +++ b/PTMagic/_defaults/_default_settings_PT_2.x/settings.general.json @@ -26,7 +26,7 @@ "GraphIntervalMinutes": 60, // The interval for the monitor market trend graph to draw points in minutes "GraphMaxTimeframeHours": 24, // This will enable you to define the timeframe that your graph for market trends covers in hours "ProfitsMaxTimeframeDays": 30, // This will enable you to define the timeframe for your dashboard profits graph in days - "RefreshSeconds": 30, // The refresh interval of your monitor main page + "DashboardChartsRefreshSeconds": 30, // The refresh interval of your dashboard charts in seconds "BagAnalyzerRefreshSeconds": 60, "BuyAnalyzerRefreshSeconds": 60, "MaxDashboardBuyEntries": 5, // The number of coins in your Possible Buy List on the dashboard. Set to 0 to hide the list completely diff --git a/_Development/DevSettings/settings.general.json b/_Development/DevSettings/settings.general.json index 103d21d..3e13de7 100644 --- a/_Development/DevSettings/settings.general.json +++ b/_Development/DevSettings/settings.general.json @@ -26,7 +26,7 @@ "GraphIntervalMinutes": 60, // The interval for the monitor market trend graph to draw points in minutes "GraphMaxTimeframeHours": 24, // This will enable you to define the timeframe that your graph for market trends covers in hours "ProfitsMaxTimeframeDays": 30, // This will enable you to define the timeframe for your dashboard profits graph in days - "RefreshSeconds": 30, // The refresh interval of your monitor main page + "DashboardChartsRefreshSeconds": 30, // The refresh interval of your dashboard charts in seconds "BagAnalyzerRefreshSeconds": 60, "BuyAnalyzerRefreshSeconds": 60, "MaxDashboardBuyEntries": 5, // The number of coins in your Possible Buy List on the dashboard. Set to 0 to hide the list completely From 659135014266ec7ac78c8162999f0ccb24538469 Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Sun, 4 Feb 2024 12:12:39 +0900 Subject: [PATCH 12/19] Trend Chart Points --- Monitor/Pages/_get/DashboardBottom.cshtml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index 6b66682..046e4c7 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -349,6 +349,7 @@