From 28c12e6d5a1c7be0fac390d9511d592b4fd5fbe3 Mon Sep 17 00:00:00 2001 From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:53:49 +0900 Subject: [PATCH] Dashboard Bottom --- Core/DataObjects/PTMagicData.cs | 98 +++--- Core/DataObjects/ProfitTrailerData.cs | 301 +++++++++++------- Core/Main/PTMagic.cs | 12 +- Monitor/Pages/Index.cshtml | 19 +- Monitor/Pages/SalesAnalyzer.cshtml | 4 +- Monitor/Pages/SalesAnalyzer.cshtml.cs | 2 + Monitor/Pages/SettingsGeneral.cshtml | 6 +- Monitor/Pages/SettingsGeneral.cshtml.cs | 11 +- Monitor/Pages/_get/DashboardBottom.cshtml | 256 +++++++++------ Monitor/Pages/_get/DashboardBottom.cshtml.cs | 182 +++++------ .../settings.general.json | 1 - .../DevSettings/settings.general.json | 1 - 12 files changed, 521 insertions(+), 372 deletions(-) diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index a7d6bde..298c2bf 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Text; namespace Core.Main.DataObjects.PTMagicData { - #region Settings Objects public class GeneralSettingsWrapper { public GeneralSettings GeneralSettings { get; set; } @@ -21,7 +19,7 @@ namespace Core.Main.DataObjects.PTMagicData public SecureSettings SecureSettings { get; set; } } - #region GeneralSettings + public class GeneralSettings { public Application Application { get; set; } @@ -43,7 +41,7 @@ namespace Core.Main.DataObjects.PTMagicData public string ProfitTrailerDefaultSettingName { get; set; } = "default"; public int FloodProtectionMinutes { get; set; } = 15; public string Exchange { get; set; } - public double StartBalance { get; set; } = 0; + //public double StartBalance { get; set; } = 0; public string InstanceName { get; set; } = "PT Magic"; public string TimezoneOffset { get; set; } = "+0:00"; public string MainFiatCurrency { get; set; } = "USD"; @@ -106,9 +104,7 @@ namespace Core.Main.DataObjects.PTMagicData public Int64 ChatId { get; set; } public bool SilentMode { get; set; } = false; } - #endregion - #region AnalyzerSettings public class AnalyzerSettings { public MarketAnalyzer MarketAnalyzer { get; set; } @@ -244,18 +240,12 @@ namespace Core.Main.DataObjects.PTMagicData [DefaultValue(0)] public int HoursSinceTriggered { get; set; } = 0; } - #endregion - #region SecureSettings public class SecureSettings { public string MonitorPassword { get; set; } = ""; } - #endregion - #endregion - - #region Market Analyzer Objects public class Market { public int Position; @@ -291,9 +281,7 @@ namespace Core.Main.DataObjects.PTMagicData public DateTime FirstSeen = Constants.confMinDate; public DateTime LastSeen = Constants.confMaxDate; } - #endregion - - #region Summary Objects + public class Summary { public string Version { get; set; } = ""; @@ -324,14 +312,26 @@ namespace Core.Main.DataObjects.PTMagicData public string SellStrategy { get; set; } = ""; public string MainMarket { get; set; } = ""; public double MainMarketPrice { get; set; } = 0; - public string MainFiatCurrency { get; set; } = "USD"; - public double MainFiatCurrencyExchangeRate { get; set; } = 1; + private PropertiesData _propertiesData = new PropertiesData(); + public string MainFiatCurrency => _propertiesData.Currency; + private SummaryData _summaryData = new SummaryData(); + public double MainFiatCurrencyExchangeRate => _summaryData.FiatConversionRate; public List BuyStrategies { get; set; } = new List(); public List SellStrategies { get; set; } = new List(); public List DCABuyStrategies { get; set; } = new List(); public List DCASellStrategies { get; set; } = new List(); } - + public class PropertiesData + { + public string Currency { get; set; } = ""; + public bool Shorting { get; set; } = false; + public bool Margin { get; set; } = false; + public string UpTime { get; set; } = ""; + public int Port { get; set; } = 0; + public bool IsLeverageExchange { get; set; } = false; + public string BaseUrl { get; set; } = ""; + } + public class StrategySummary { public string Name { get; set; } = ""; @@ -364,22 +364,7 @@ namespace Core.Main.DataObjects.PTMagicData public List DCABuyStrategies { get; set; } = new List(); public List DCASellStrategies { get; set; } = new List(); } - #endregion - - #region Properties Objects - public class Properties - { - public string Currency { get; set; } = ""; - public bool Shorting { get; set; } = false; - public bool Margin { get; set; } = false; - public string UpTime { get; set; } = ""; - public int Port { get; set; } = 0; - public bool IsLeverageExchange { get; set; } = false; - public string BaseUrl { get; set; } = ""; - } - #endregion - - #region Transaction Objects + public class Transaction { public string GUID { get; set; } = ""; @@ -397,9 +382,7 @@ namespace Core.Main.DataObjects.PTMagicData return result.DateTime; } } - #endregion - - #region SingleMarketSettingSummary Objects + public class SingleMarketSettingSummary { public string Market { get; set; } = ""; @@ -415,11 +398,8 @@ namespace Core.Main.DataObjects.PTMagicData public double LastPrice { get; set; } = 0; public double Last24hVolume { get; set; } = 0; } - #endregion - - #region Profit Trailer JSON Objects - - public class SellLogData + + public class SellLogData { public double SoldAmount { get; set; } public DateTime SoldDate { get; set; } @@ -445,19 +425,39 @@ namespace Core.Main.DataObjects.PTMagicData public double SalesWeek { get; set; } public double ProfitWeek { get; set; } public double ProfitPercWeek { get; set; } - public double SalesMonth { get; set; } - public double ProfitMonth { get; set; } - public double ProfitPercMonth { get; set; } + public double SalesThisMonth { get; set; } + public double ProfitThisMonth { get; set; } + public double ProfitPercThisMonth { get; set; } + public double SalesLastMonth { get; set; } + public double ProfitLastMonth { get; set; } + public double ProfitPercLastMonth { get; set; } public double TotalProfit { get; set; } public double TotalSales { get; set; } public double TotalProfitPerc { get; set; } public double FundingToday { get; set; } public double FundingYesterday { get; set; } public double FundingWeek { get; set; } - public double FundingMonth { get; set; } + public double FundingThisMonth { get; set; } + public double FundingLastMonth { get; set; } public double FundingTotal { get; set; } } + public class DailyStatsData + { + public string Date { get; set; } + public double TotalSales { get; set; } + public double TotalBuys { get; set; } + public double TotalProfitCurrency { get; set; } + public int Order { get; set; } + } + + public class DailyPNLData + { + public string Date { get; set; } + public double CumulativeProfitCurrency { get; set; } + public double Order { get; set; } + } + public class PTStrategy { public string type { get; set; } @@ -534,15 +534,13 @@ namespace Core.Main.DataObjects.PTMagicData } public class SummaryData - { - public double Balance { get; set; } + { public double Balance { get; set; } public double StartBalance { get; set; } + public double FiatConversionRate { get; set; } public double PairsValue { get; set; } public double DCAValue { get; set; } public double PendingValue { get; set; } public double DustValue { get; set; } public string Market { get; set; } } - - #endregion } \ No newline at end of file diff --git a/Core/DataObjects/ProfitTrailerData.cs b/Core/DataObjects/ProfitTrailerData.cs index 10b8231..465a205 100644 --- a/Core/DataObjects/ProfitTrailerData.cs +++ b/Core/DataObjects/ProfitTrailerData.cs @@ -15,18 +15,32 @@ namespace Core.Main.DataObjects public class ProfitTrailerData { private SummaryData _summary = null; - private Properties _properties = null; - private List _stats = null; + private PropertiesData _properties = null; + private StatsData _stats = null; + private List _dailyStats = new List(); + private List _dailyPNL = new List(); private List _sellLog = new List(); private List _dcaLog = new List(); private List _buyLog = new List(); private string _ptmBasePath = ""; private PTMagicConfiguration _systemConfiguration = null; private TransactionData _transactionData = null; - private DateTime _statsRefresh = DateTime.UtcNow,_buyLogRefresh = DateTime.UtcNow, _sellLogRefresh = DateTime.UtcNow, _dcaLogRefresh = DateTime.UtcNow, _summaryRefresh = DateTime.UtcNow, _propertiesRefresh = DateTime.UtcNow; - private volatile object _statsLock = new object(),_buyLock = new object(), _sellLock = new object(), _dcaLock = new object(), _summaryLock = new object(), _propertiesLock = new object(); - private TimeSpan? _offsetTimeSpan = null; - + private DateTime _dailyStatsRefresh = DateTime.UtcNow; + private DateTime _dailyPNLRefresh = DateTime.UtcNow; + private DateTime _statsRefresh = DateTime.UtcNow; + private DateTime _buyLogRefresh = DateTime.UtcNow; + private DateTime _sellLogRefresh = DateTime.UtcNow; + private DateTime _dcaLogRefresh = DateTime.UtcNow; + private DateTime _summaryRefresh = DateTime.UtcNow; + private DateTime _propertiesRefresh = DateTime.UtcNow; + private volatile object _dailyStatsLock = new object(); + private volatile object _dailyPNLLock = new object(); + private volatile object _statsLock = new object(); + private volatile object _buyLock = new object(); + private volatile object _sellLock = new object(); + private volatile object _dcaLock = new object(); + private volatile object _summaryLock = new object(); + private volatile object _propertiesLock = new object(); private TimeSpan? _offsetTimeSpan = null; public void DoLog(string message) { // Implement your logging logic here @@ -78,11 +92,25 @@ namespace Core.Main.DataObjects } } } - + return _summary; } } - public Properties Properties + private SummaryData BuildSummaryData(dynamic PTData) + { + return new SummaryData() + { + Market = PTData.market, + FiatConversionRate = PTData.priceDataFiatConversionRate, + Balance = PTData.realBalance, + PairsValue = PTData.totalPairsCurrentValue, + DCAValue = PTData.totalDCACurrentValue, + PendingValue = PTData.totalPendingCurrentValue, + DustValue = PTData.totalDustCurrentValue, + StartBalance = PTData.startBalance, + }; + } + public PropertiesData Properties { get { @@ -102,8 +130,20 @@ namespace Core.Main.DataObjects return _properties; } } - - public List Stats + private PropertiesData BuildProptertiesData(dynamic PTProperties) + { + return new PropertiesData() + { + Currency = PTProperties.currency, + Shorting = PTProperties.shorting, + Margin = PTProperties.margin, + UpTime = PTProperties.upTime, + Port = PTProperties.port, + IsLeverageExchange = PTProperties.isLeverageExchange, + BaseUrl = PTProperties.baseUrl + }; + } + public StatsData Stats { get { @@ -116,7 +156,7 @@ namespace Core.Main.DataObjects dynamic statsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats"); JObject statsDataJObject = statsDataJson as JObject; JObject basicSection = (JObject)statsDataJObject["basic"]; - _stats = new List { BuildStatsData(basicSection) }; + _stats = BuildStatsData(basicSection); _statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); } } @@ -124,13 +164,103 @@ namespace Core.Main.DataObjects return _stats; } } - - + private StatsData BuildStatsData(dynamic statsDataJson) + { + return new StatsData() + { + SalesToday = statsDataJson["totalSalesToday"], + ProfitToday = statsDataJson["totalProfitToday"], + ProfitPercToday = statsDataJson["totalProfitPercToday"], + SalesYesterday = statsDataJson["totalSalesYesterday"], + ProfitYesterday = statsDataJson["totalProfitYesterday"], + ProfitPercYesterday = statsDataJson["totalProfitPercYesterday"], + SalesWeek = statsDataJson["totalSalesWeek"], + ProfitWeek = statsDataJson["totalProfitWeek"], + ProfitPercWeek = statsDataJson["totalProfitPercWeek"], + SalesThisMonth = statsDataJson["totalSalesThisMonth"], + ProfitThisMonth = statsDataJson["totalProfitThisMonth"], + ProfitPercThisMonth = statsDataJson["totalProfitPercThisMonth"], + SalesLastMonth = statsDataJson["totalSalesLastMonth"], + ProfitLastMonth = statsDataJson["totalProfitLastMonth"], + ProfitPercLastMonth = statsDataJson["totalProfitPercLastMonth"], + TotalProfit = statsDataJson["totalProfit"], + TotalSales = statsDataJson["totalSales"], + TotalProfitPerc = statsDataJson["totalProfitPerc"], + FundingToday = statsDataJson["totalFundingToday"], + FundingYesterday = statsDataJson["totalFundingYesterday"], + FundingWeek = statsDataJson["totalFundingWeek"], + FundingThisMonth = statsDataJson["totalFundingThisMonth"], + FundingLastMonth = statsDataJson["totalFundingLastMonth"], + FundingTotal = statsDataJson["totalFunding"] + }; + } + public List DailyStats + { + get + { + if (_dailyStats == null || DateTime.UtcNow > _dailyStatsRefresh) + { + lock (_dailyStatsLock) + { + if (_dailyStats == null || DateTime.UtcNow > _dailyStatsRefresh) + { + dynamic dailyStatsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats"); + JObject dailyStatsDataJObject = dailyStatsDataJson as JObject; + JArray dailyStatsSection = (JArray)dailyStatsDataJObject["extra"]["dailyStats"]; + _dailyStats = dailyStatsSection.Select(j => BuildDailyStatsData(j as JObject)).ToList(); + _dailyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + } + } + } + return _dailyStats; + } + } + private DailyStatsData BuildDailyStatsData(dynamic dailyStatsDataJson) + { + return new DailyStatsData() + { + Date = dailyStatsDataJson["date"], + TotalSales = dailyStatsDataJson["totalSales"], + TotalBuys = dailyStatsDataJson["totalBuys"], + TotalProfitCurrency = dailyStatsDataJson["totalProfitCurrency"], + Order = dailyStatsDataJson["order"], + }; + } + public List DailyPNL + { + get + { + if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh) + { + lock (_dailyPNLLock) + { + if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh) + { + dynamic dailyPNLDataJson = GetDataFromProfitTrailer("/api/v2/data/stats"); + JObject dailyPNLDataJObject = dailyPNLDataJson as JObject; + JArray dailyPNLSection = (JArray)dailyPNLDataJObject["extra"]["dailyPNLStats"]; + _dailyPNL = dailyPNLSection.Select(j => BuildDailyPNLData(j as JObject)).ToList(); + _dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1); + } + } + } + return _dailyPNL; + } + } + private DailyPNLData BuildDailyPNLData(dynamic dailyPNLDataJson) + { + return new DailyPNLData() + { + Date = dailyPNLDataJson["date"], + CumulativeProfitCurrency = dailyPNLDataJson["cumulativeProfitCurrency"], + Order = dailyPNLDataJson["order"], + }; + } public List SellLog { get { - + if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh)) { lock (_sellLock) @@ -139,16 +269,16 @@ namespace Core.Main.DataObjects 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); @@ -167,7 +297,7 @@ namespace Core.Main.DataObjects exitLoop = true; } } - + // Update sell log refresh time _sellLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds -1); } @@ -177,7 +307,7 @@ namespace Core.Main.DataObjects } } - + public List DCALog { get @@ -203,7 +333,6 @@ namespace Core.Main.DataObjects () => { pendingData = GetDataFromProfitTrailer("/api/v2/data/pending", true); - }, () => { @@ -276,20 +405,21 @@ namespace Core.Main.DataObjects return (this.Summary.DustValue); } - + + public double GetSnapshotBalance(DateTime snapshotDateTime) { - double result = _systemConfiguration.GeneralSettings.Application.StartBalance; - + double result = _summary.StartBalance; + result += this.SellLog.FindAll(sl => sl.SoldDate.Date < snapshotDateTime.Date).Sum(sl => sl.Profit); result += this.TransactionData.Transactions.FindAll(t => t.UTCDateTime < snapshotDateTime).Sum(t => t.Amount); - + // Calculate holdings for snapshot date result += this.DCALog.FindAll(pairs => pairs.FirstBoughtDate <= snapshotDateTime).Sum(pairs => pairs.CurrentValue); - + return result; } - + private dynamic GetDataFromProfitTrailer(string callPath, bool arrayReturned = false) { string rawBody = ""; @@ -297,15 +427,15 @@ namespace Core.Main.DataObjects callPath, callPath.Contains("?") ? "&" : "?", _systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken); - + // Get the data from PT Debug.WriteLine(String.Format("{0} - Calling '{1}'", DateTime.UtcNow, url)); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.AutomaticDecompression = DecompressionMethods.GZip; request.KeepAlive = true; - + WebResponse response = request.GetResponse(); - + using (Stream dataStream = response.GetResponseStream()) { StreamReader reader = new StreamReader(dataStream); @@ -314,8 +444,8 @@ namespace Core.Main.DataObjects } response.Close(); - - + + if (!arrayReturned) { return JObject.Parse(rawBody); @@ -324,62 +454,9 @@ namespace Core.Main.DataObjects { return JArray.Parse(rawBody); } - - - } - private SummaryData BuildSummaryData(dynamic PTData) - { - return new SummaryData() - { - Market = PTData.market, - Balance = PTData.realBalance, - PairsValue = PTData.totalPairsCurrentValue, - DCAValue = PTData.totalDCACurrentValue, - PendingValue = PTData.totalPendingCurrentValue, - DustValue = PTData.totalDustCurrentValue - }; - } - private Properties BuildProptertiesData(dynamic PTProperties) - { - return new Properties() - { - Currency = PTProperties.currency, - Shorting = PTProperties.shorting, - Margin = PTProperties.margin, - UpTime = PTProperties.upTime, - Port = PTProperties.port, - IsLeverageExchange = PTProperties.isLeverageExchange, - BaseUrl = PTProperties.baseUrl - }; - } - private StatsData BuildStatsData(dynamic statsDataJson) - { - return new StatsData() - { - SalesToday = statsDataJson["totalSalesToday"], - ProfitToday = statsDataJson["totalProfitToday"], - ProfitPercToday = statsDataJson["totalProfitPercToday"], - SalesYesterday = statsDataJson["totalSalesYesterday"], - ProfitYesterday = statsDataJson["totalProfitYesterday"], - ProfitPercYesterday = statsDataJson["totalProfitPercYesterday"], - SalesWeek = statsDataJson["totalSalesWeek"], - ProfitWeek = statsDataJson["totalProfitWeek"], - ProfitPercWeek = statsDataJson["totalProfitPercWeek"], - SalesMonth = statsDataJson["totalSalesThisMonth"], - ProfitMonth = statsDataJson["totalProfitThisMonth"], - ProfitPercMonth = statsDataJson["totalProfitPercThisMonth"], - TotalProfit = statsDataJson["totalProfit"], - TotalSales = statsDataJson["totalSales"], - TotalProfitPerc = statsDataJson["totalProfitPerc"], - FundingToday = statsDataJson["totalFundingToday"], - FundingYesterday = statsDataJson["totalFundingYesterday"], - FundingWeek = statsDataJson["totalFundingWeek"], - FundingMonth = statsDataJson["totalFundingThisMonth"], - FundingTotal = statsDataJson["totalFunding"] - }; - } + private void BuildSellLogData(dynamic rawSellLogData) { foreach (var rsld in rawSellLogData.data) @@ -393,20 +470,23 @@ namespace Core.Main.DataObjects sellLogData.AverageBuyPrice = rsld.avgPrice; sellLogData.TotalCost = rsld.totalCost; sellLogData.Profit = rsld.profitCurrency; - - + + //Convert Unix Timestamp to Datetime System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc); dtDateTime = dtDateTime.AddSeconds((double)rsld.soldDate).ToUniversalTime(); - + + // Profit Trailer sales are saved in UTC DateTimeOffset ptSoldDate = DateTimeOffset.Parse(dtDateTime.Year.ToString() + "-" + dtDateTime.Month.ToString("00") + "-" + dtDateTime.Day.ToString("00") + "T" + dtDateTime.Hour.ToString("00") + ":" + dtDateTime.Minute.ToString("00") + ":" + dtDateTime.Second.ToString("00"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); - + + // Convert UTC sales time to local offset time + ptSoldDate = ptSoldDate.ToOffset(OffsetTimeSpan); - + sellLogData.SoldDate = ptSoldDate.DateTime; - + _sellLog.Add(sellLogData); } } @@ -415,23 +495,22 @@ namespace Core.Main.DataObjects { // Parse DCA data _dcaLog.AddRange(ParsePairsData(rawDCALogData, true)); - + // Parse Pairs data _dcaLog.AddRange(ParsePairsData(rawPairsLogData, false)); - + // Parse pending pairs data _dcaLog.AddRange(ParsePairsData(rawPendingLogData, false)); - + // Parse watch only pairs data _dcaLog.AddRange(ParsePairsData(rawWatchModeLogData, false)); - } // Parse the pairs data from PT to our own common data structure. private List ParsePairsData(dynamic pairsData, bool processBuyStrategies) { List pairs = new List(); - + foreach (var pair in pairsData) { DCALogData dcaLogData = new DCALogData(); @@ -452,7 +531,7 @@ namespace Core.Main.DataObjects dcaLogData.BuyStrategy = pair.buyStrategy == null ? "" : pair.buyStrategy; dcaLogData.SellStrategy = pair.sellStrategy == null ? "" : pair.sellStrategy; dcaLogData.IsTrailing = false; - + // See if they are using PT 2.5 (buyStrategiesData) or 2.4 (buyStrategies) var buyStrats = pair.buyStrategies != null ? pair.buyStrategies : pair.buyStrategiesData.data; if (buyStrats != null && processBuyStrategies) @@ -470,7 +549,7 @@ namespace Core.Main.DataObjects buyStrategy.Decimals = bs.decimals; buyStrategy.IsTrailing = bs.trailing; buyStrategy.IsTrue = bs.strategyResult; - + dcaLogData.BuyStrategies.Add(buyStrategy); } } @@ -492,9 +571,9 @@ namespace Core.Main.DataObjects sellStrategy.Decimals = ss.decimals; sellStrategy.IsTrailing = ss.trailing; sellStrategy.IsTrue = ss.strategyResult; - + dcaLogData.SellStrategies.Add(sellStrategy); - + // Find the target percentage gain to sell. if (sellStrategy.Name.Contains("GAIN", StringComparison.InvariantCultureIgnoreCase)) { @@ -506,14 +585,14 @@ namespace Core.Main.DataObjects } } } - + // Calculate current value dcaLogData.CurrentValue = dcaLogData.CurrentPrice * dcaLogData.Amount; - + // Convert Unix Timestamp to Datetime System.DateTime rdldDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc); rdldDateTime = rdldDateTime.AddSeconds((double)pair.firstBoughtDate).ToUniversalTime(); - + // Profit Trailer bought times are saved in UTC if (pair.firstBoughtDate > 0) { @@ -528,7 +607,7 @@ namespace Core.Main.DataObjects { dcaLogData.FirstBoughtDate = Constants.confMinDate; } - + _dcaLog.Add(dcaLogData); } @@ -545,7 +624,7 @@ namespace Core.Main.DataObjects buyLogData.CurrentPrice = rbld.currentPrice; buyLogData.PercChange = rbld.percChange; buyLogData.Volume24h = rbld.volume; - + if (rbld.positive != null) { buyLogData.IsTrailing = ((string)(rbld.positive)).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1; @@ -554,10 +633,10 @@ namespace Core.Main.DataObjects else { // Parse buy strategies - + // See if they are using PT 2.5 (buyStrategiesData) or 2.4 (buyStrategies) var buyStrats = rbld.buyStrategies != null ? rbld.buyStrategies : rbld.buyStrategiesData.data; - + if (buyStrats != null) { foreach (var bs in buyStrats) @@ -573,17 +652,17 @@ namespace Core.Main.DataObjects buyStrategy.Decimals = bs.decimals; buyStrategy.IsTrailing = bs.trailing; buyStrategy.IsTrue = bs.strategyResult; - + // Is SOM? buyLogData.IsSom = buyLogData.IsSom || buyStrategy.Name.Contains("som enabled", StringComparison.OrdinalIgnoreCase); - + // Is the pair trailing? buyLogData.IsTrailing = buyLogData.IsTrailing || buyStrategy.IsTrailing; buyLogData.IsTrue = buyLogData.IsTrue || buyStrategy.IsTrue; - + // True status strategy count total buyLogData.TrueStrategyCount += buyStrategy.IsTrue ? 1 : 0; - + // Add buyLogData.BuyStrategies.Add(buyStrategy); } diff --git a/Core/Main/PTMagic.cs b/Core/Main/PTMagic.cs index 9c6e1b3..cd89412 100644 --- a/Core/Main/PTMagic.cs +++ b/Core/Main/PTMagic.cs @@ -872,7 +872,7 @@ namespace Core.Main this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version); // Get latest main fiat currency exchange rate - this.GetMainFiatCurrencyDetails(); + // this.GetMainFiatCurrencyDetails(); // Load current PT files this.LoadCurrentProfitTrailerProperties(); @@ -1127,10 +1127,10 @@ namespace Core.Main } } - private void GetMainFiatCurrencyDetails() - { - this.LastRuntimeSummary.MainFiatCurrency = this.LastMainFiatCurrency; - this.LastRuntimeSummary.MainFiatCurrencyExchangeRate = this.LastMainFiatCurrencyExchangeRate; + //private void GetMainFiatCurrencyDetails() + //{ + //this.LastRuntimeSummary.MainFiatCurrency = this.PropertiesData.Currency; + //this.LastRuntimeSummary.MainFiatCurrencyExchangeRate = this.LastMainFiatCurrencyExchangeRate; // if (this.LastFiatCurrencyCheck < DateTime.UtcNow.AddHours(-12) && !this.PTMagicConfiguration.GeneralSettings.Application.MainFiatCurrency.Equals("USD", StringComparison.InvariantCultureIgnoreCase)) // { @@ -1154,7 +1154,7 @@ namespace Core.Main // this.LastMainFiatCurrencyExchangeRate = 1; // } // } - } + //} // Get current PT properties private void LoadCurrentProfitTrailerProperties() diff --git a/Monitor/Pages/Index.cshtml b/Monitor/Pages/Index.cshtml index fe49026..930214b 100644 --- a/Monitor/Pages/Index.cshtml +++ b/Monitor/Pages/Index.cshtml @@ -33,6 +33,11 @@ $("#baglist-refresh-icon").html(''); $("#buylist-refresh-icon").html(''); + // Add the page refresh code here + setTimeout(function(){ + location.reload(); + }, 60 * 60 * 1000); // 60 minutes + // Clear exisitng interval to stop multiple attempts to load at the same time. if (intervalDashboardTop != null) { @@ -64,13 +69,13 @@ var loadDashboardBottom = function () { //destroy all d3 svg graph to avoid memory leak - $(".nvtooltip").remove(); - $("svg > *").remove(); - $("svg").remove(); - nv.charts = {}; - nv.graphs = []; - nv.logs = {}; - nv.tooltip = {}; + //$(".nvtooltip").remove(); + //$("svg > *").remove(); + //$("svg").remove(); + //nv.charts = {}; + //nv.graphs = []; + //nv.logs = {}; + //nv.tooltip = {}; // Clear exisitng interval to stop multiple attempts to load at the same time. if (intervalDashboardBottom != null) diff --git a/Monitor/Pages/SalesAnalyzer.cshtml b/Monitor/Pages/SalesAnalyzer.cshtml index 28240e1..6b646ce 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml +++ b/Monitor/Pages/SalesAnalyzer.cshtml @@ -26,7 +26,7 @@ } } Total Current Value:   @totalCurrentValueString @Model.Summary.MainMarket - Starting Value:   @Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance   @Model.Summary.MainMarket + Starting Value:   @Model.SummaryData.StartBalance   @Model.Summary.MainMarket @@ -64,7 +64,7 @@ double totalProfit = 0; 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 percentGain = Math.Round(totalProfit / Model.SummaryData.StartBalance * 100, 2); double avgDailyGain = Model.DailyGains.Values.Average(dg => dg); double avgMonthlyGain = Model.MonthlyGains.Values.Average(dg => dg); string percentGainText = percentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%"; diff --git a/Monitor/Pages/SalesAnalyzer.cshtml.cs b/Monitor/Pages/SalesAnalyzer.cshtml.cs index 74d1b73..049fdb2 100644 --- a/Monitor/Pages/SalesAnalyzer.cshtml.cs +++ b/Monitor/Pages/SalesAnalyzer.cshtml.cs @@ -12,6 +12,7 @@ namespace Monitor.Pages public class SalesAnalyzer : _Internal.BasePageModelSecure { public ProfitTrailerData PTData = null; + public SummaryData SummaryData { get; set; } public string TradesChartDataJSON = ""; public string ProfitChartDataJSON = ""; public string BalanceChartDataJSON = ""; @@ -31,6 +32,7 @@ namespace Monitor.Pages private void BindData() { PTData = this.PtDataObject; + SummaryData = this.PTData.Summary; // Convert local offset time to UTC TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); diff --git a/Monitor/Pages/SettingsGeneral.cshtml b/Monitor/Pages/SettingsGeneral.cshtml index 82b7166..1c9f2e8 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml +++ b/Monitor/Pages/SettingsGeneral.cshtml @@ -131,12 +131,12 @@ *@ -
+ @*
- +
-
+
*@
diff --git a/Monitor/Pages/SettingsGeneral.cshtml.cs b/Monitor/Pages/SettingsGeneral.cshtml.cs index 39f6035..57884f2 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml.cs +++ b/Monitor/Pages/SettingsGeneral.cshtml.cs @@ -1,16 +1,19 @@ 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; + namespace Monitor.Pages { public class SettingsGeneralModel : _Internal.BasePageModelSecure { - public string ValidationMessage = ""; + public string ValidationMessage = ""; + public ProfitTrailerData PTData = null; + public SummaryData SummaryData { get; set; } private string GetTimezoneOffsetString(TimeZoneInfo tzi) { @@ -51,6 +54,8 @@ namespace Monitor.Pages public void OnGet() { base.Init(); + PTData = this.PtDataObject; + SummaryData = this.PTData.Summary; string notification = GetStringParameter("n", ""); if (notification.Equals("BackupRestored")) @@ -68,7 +73,7 @@ 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.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"]; diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml b/Monitor/Pages/_get/DashboardBottom.cshtml index d15c6d4..5ca12c3 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml +++ b/Monitor/Pages/_get/DashboardBottom.cshtml @@ -24,7 +24,7 @@
-
+ @*
*@ @{ string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")); if (Model.totalCurrentValue > 100) { @@ -34,8 +34,8 @@
- Start:   @Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance @Model.Summary.MainMarket -     Gain: @Math.Round(((Model.totalCurrentValue - Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) * 100, 2)% + Start:   @Model.SummaryData.StartBalance @Model.Summary.MainMarket +     Gain: @Math.Round(((Model.totalCurrentValue - Model.SummaryData.StartBalance) / Model.SummaryData.StartBalance) * 100, 2)%
@@ -49,7 +49,7 @@
-
+ @*
*@
@if (!Model.ProfitChartDataJSON.Equals("")) {
@@ -61,6 +61,7 @@
+
@@ -115,53 +116,58 @@
-
-
+ @*
+
*@

Sales Overviewmore

@{ - var overviewStats = Model.StatsData.FirstOrDefault(); // todaysStats is a new variable + var overviewStats = Model.StatsData; // todaysStats is a new variable var todaysSales = overviewStats.SalesToday; var todaysProfit = overviewStats.ProfitToday; var todaysFunding = overviewStats.FundingToday; var todaysPercentGain = overviewStats.ProfitPercToday; - var todaysFundingGain = todaysPercentGain * ((todaysProfit - todaysFunding) / todaysProfit); + //var todaysFundingGain = todaysPercentGain * ((todaysProfit - todaysFunding) / todaysProfit); - var yesterdaysSales = overviewStats.SalesYesterday; var yesterdaysProfit = overviewStats.ProfitYesterday; var yesterdaysFunding = overviewStats.FundingYesterday; var yesterdaysPercentGain = overviewStats.ProfitPercYesterday; - var yesterdaysFundingGain = yesterdaysPercentGain * ((yesterdaysProfit + yesterdaysFunding) / yesterdaysProfit); + //var yesterdaysFundingGain = yesterdaysPercentGain * ((yesterdaysProfit + yesterdaysFunding) / yesterdaysProfit); var last7DaysSales = overviewStats.SalesWeek; var last7DaysProfit = overviewStats.ProfitWeek; var last7DaysFunding = overviewStats.FundingWeek; var last7DaysPercentGain = overviewStats.ProfitPercWeek; - var last7DaysFundingGain = last7DaysPercentGain * ((last7DaysProfit + last7DaysFunding) / last7DaysProfit); + //var last7DaysFundingGain = last7DaysPercentGain * ((last7DaysProfit + last7DaysFunding) / last7DaysProfit); - var last30DaysSales = overviewStats.SalesMonth; - var last30DaysProfit = overviewStats.ProfitMonth; - var last30DaysFunding = overviewStats.FundingMonth; - var last30DaysPercentGain = overviewStats.ProfitPercMonth; - var last30DaysFundingGain = last30DaysPercentGain * ((last30DaysProfit + last30DaysFunding) / last30DaysProfit); + var thisMonthSales = overviewStats.SalesThisMonth; + var thisMonthProfit = overviewStats.ProfitThisMonth; + var thisMonthFunding = overviewStats.FundingThisMonth; + var thisMonthPercentGain = overviewStats.ProfitPercThisMonth; + //var thisMonthFundingGain = thisMonthPercentGain * ((thisMonthProfit + thisMonthFunding) / thisMonthProfit); + + var lastMonthSales = overviewStats.SalesLastMonth; + var lastMonthProfit = overviewStats.ProfitLastMonth; + var lastMonthFunding = overviewStats.FundingLastMonth; + var lastMonthPercentGain = overviewStats.ProfitPercLastMonth; + //var lastMonthFundingGain = lastMonthPercentGain * ((lastMonthProfit + lastMonthFunding) / lastMonthProfit); var totalSales = overviewStats.TotalSales; var totalProfit = overviewStats.TotalProfit; var totalFunding = overviewStats.FundingTotal; var totalProfitPercent = overviewStats.TotalProfitPerc; - var totalFundingGain = totalProfitPercent * ((totalProfit + totalFunding) / totalProfit); - - double todaysProfitFiat = Math.Round((todaysProfit + todaysFunding) * Model.Summary.MainMarketPrice, 2); - double yesterdaysProfitFiat = Math.Round((yesterdaysProfit + yesterdaysFunding) * Model.Summary.MainMarketPrice, 2); - double last7DaysProfitFiat = Math.Round((last7DaysProfit + last7DaysFunding) * Model.Summary.MainMarketPrice, 2); - double last30DaysProfitFiat = Math.Round((last30DaysProfit + last30DaysFunding) * Model.Summary.MainMarketPrice, 2); - double totalProfitFiat = Math.Round((totalProfit + totalFunding) * Model.Summary.MainMarketPrice, 2); - + //var totalFundingGain = totalProfitPercent * ((totalProfit + totalFunding) / totalProfit); + double todaysProfitFiat = Math.Round((todaysProfit + todaysFunding) * Model.PTData.Summary.FiatConversionRate, 2); + double yesterdaysProfitFiat = Math.Round((yesterdaysProfit + yesterdaysFunding) * Model.PTData.Summary.FiatConversionRate, 2); + double last7DaysProfitFiat = Math.Round((last7DaysProfit + last7DaysFunding) * Model.PTData.Summary.FiatConversionRate, 2); + double thisMonthProfitFiat = Math.Round((thisMonthProfit + thisMonthFunding) * Model.PTData.Summary.FiatConversionRate, 2); + double lastMonthProfitFiat = Math.Round((lastMonthProfit + lastMonthFunding) * Model.PTData.Summary.FiatConversionRate, 2); + double totalProfitFiat = Math.Round((totalProfit + totalFunding) * Model.PTData.Summary.FiatConversionRate, 2); + bool futuresFunding = Model.PropertiesData.IsLeverageExchange; } @@ -169,10 +175,13 @@ - - - + + @if (futuresFunding) + { + + } + @@ -180,41 +189,67 @@ - + + @if (futuresFunding) + { + + } - - + + @if (futuresFunding) + { + + } - - + + @if (futuresFunding) + { + + } - - - - - - - + + + + + @if (futuresFunding) + { + + } + + + + + + + + @if (futuresFunding) + { + + } + - + + @if (futuresFunding) + { + + } -
SalesProfit @Model.Summary.MainMarketFunding@Model.Summary.MainFiatCurrencyProfit @Model.PTData.Summary.Market GainFunding@Model.PTData.Properties.Currency
Today @overviewStats.SalesToday @todaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@todaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@todaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%@todaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(todaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))@todaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
Yesterday @yesterdaysSales @yesterdaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@yesterdaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@yesterdaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%@yesterdaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(yesterdaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))@yesterdaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
Last 7 Days @last7DaysSales @last7DaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@last7DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@last7DaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%@last7DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(last7DaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))@last7DaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
Last 30 Days@last30DaysSales@last30DaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@last30DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(last30DaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))@last30DaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%This Month@thisMonthSales@thisMonthProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@thisMonthPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%@thisMonthFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(thisMonthProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))
Last Month@lastMonthSales@lastMonthProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@lastMonthPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%@lastMonthFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(lastMonthProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))
Total @totalSales @totalProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@totalFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@totalProfitPercent.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%@totalFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))@Html.Raw(totalProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))@totalFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
@@ -226,74 +261,101 @@ + + + + diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs index 3f5dbea..890730d 100644 --- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs +++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs @@ -6,14 +6,19 @@ using Core.Main; using Core.Helper; using Core.Main.DataObjects; using Core.Main.DataObjects.PTMagicData; -using Core.MarketAnalyzer; +using System.Globalization; +using System.Text; namespace Monitor.Pages { public class DashboardBottomModel : _Internal.BasePageModelSecureAJAX { public ProfitTrailerData PTData = null; - public List StatsData { get; set; } + public StatsData StatsData { get; set; } + public PropertiesData PropertiesData { get; set; } + public SummaryData SummaryData { get; set; } + public List DailyStats { get; set; } = new List(); + public List DailyPNL { get; set; } = new List(); public List MarketTrends { get; set; } = new List(); public string TrendChartDataJSON = ""; public string ProfitChartDataJSON = ""; @@ -35,6 +40,10 @@ namespace Monitor.Pages { PTData = this.PtDataObject; StatsData = this.PTData.Stats; + PropertiesData = this.PTData.Properties; + SummaryData = this.PTData.Summary; + List dailyStatsData = this.PTData.DailyStats; + List dailyPNLData = this.PTData.DailyPNL; // Cleanup temp files FileHelper.CleanupFilesMinutes(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar, 5); @@ -57,110 +66,101 @@ namespace Monitor.Pages BuildProfitChartData(); } private void BuildMarketTrendChartData() +{ + StringBuilder trendChartDataJSON = new StringBuilder(); + if (MarketTrends.Count > 0) { - if (MarketTrends.Count > 0) - { - TrendChartDataJSON = "["; + trendChartDataJSON.Append("["); int mtIndex = 0; foreach (MarketTrend mt in MarketTrends) { - if (mt.DisplayGraph) - { - string lineColor = ""; - if (mtIndex < Constants.ChartLineColors.Length) + if (mt.DisplayGraph) { - lineColor = Constants.ChartLineColors[mtIndex]; - } - else - { - lineColor = Constants.ChartLineColors[mtIndex - 20]; - } - - if (Summary.MarketTrendChanges.ContainsKey(mt.Name)) - { - List marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name]; - - if (marketTrendChangeSummaries.Count > 0) - { - if (!TrendChartDataJSON.Equals("[")) TrendChartDataJSON += ","; - - TrendChartDataJSON += "{"; - TrendChartDataJSON += "key: '" + SystemHelper.SplitCamelCase(mt.Name) + "',"; - TrendChartDataJSON += "color: '" + lineColor + "',"; - TrendChartDataJSON += "values: ["; - - // Get trend ticks for chart - DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0); - DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours); - DateTime endDateTime = currentDateTime; - int trendChartTicks = 0; - for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes)) + string lineColor = ""; + if (mtIndex < Constants.ChartLineColors.Length) { - List tickRange = marketTrendChangeSummaries.FindAll(m => m.TrendDateTime >= tickTime).OrderBy(m => m.TrendDateTime).ToList(); - if (tickRange.Count > 0) - { - MarketTrendChange mtc = tickRange.First(); - if (tickTime != startDateTime) TrendChartDataJSON += ",\n"; - if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0; - - TrendChartDataJSON += "{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"; - trendChartTicks++; - } + lineColor = Constants.ChartLineColors[mtIndex]; } - // Add most recent tick - List latestTickRange = marketTrendChangeSummaries.OrderByDescending(m => m.TrendDateTime).ToList(); - if (latestTickRange.Count > 0) + else { - MarketTrendChange mtc = latestTickRange.First(); - if (trendChartTicks > 0) TrendChartDataJSON += ",\n"; - if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0; - TrendChartDataJSON += "{ x: new Date('" + mtc.TrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"; + lineColor = Constants.ChartLineColors[mtIndex - 20]; + } + + if (Summary.MarketTrendChanges.ContainsKey(mt.Name)) + { + List marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name]; + + if (marketTrendChangeSummaries.Count > 0) + { + if (!trendChartDataJSON.ToString().Equals("[")) trendChartDataJSON.Append(","); + + trendChartDataJSON.Append("{"); + trendChartDataJSON.Append("key: '" + SystemHelper.SplitCamelCase(mt.Name) + "',"); + trendChartDataJSON.Append("color: '" + lineColor + "',"); + trendChartDataJSON.Append("values: ["); + + // Get trend ticks for chart + DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0); + DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours); + DateTime endDateTime = currentDateTime; + int trendChartTicks = 0; + for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes)) + { + List tickRange = marketTrendChangeSummaries.FindAll(m => m.TrendDateTime >= tickTime).OrderBy(m => m.TrendDateTime).ToList(); + if (tickRange.Count > 0) + { + MarketTrendChange mtc = tickRange.First(); + if (tickTime != startDateTime) trendChartDataJSON.Append(",\n"); + if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0; + + trendChartDataJSON.Append("{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"); + trendChartTicks++; + } + } + // Add most recent tick + List latestTickRange = marketTrendChangeSummaries.OrderByDescending(m => m.TrendDateTime).ToList(); + if (latestTickRange.Count > 0) + { + MarketTrendChange mtc = latestTickRange.First(); + if (trendChartTicks > 0) trendChartDataJSON.Append(",\n"); + if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0; + trendChartDataJSON.Append("{ x: new Date('" + mtc.TrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"); + } + trendChartDataJSON.Append("]"); + trendChartDataJSON.Append("}"); + mtIndex++; + } } - TrendChartDataJSON += "]"; - TrendChartDataJSON += "}"; - mtIndex++; - } } - } } - TrendChartDataJSON += "]"; - } + trendChartDataJSON.Append("]"); } + TrendChartDataJSON = trendChartDataJSON.ToString(); +} private void BuildProfitChartData() { - int tradeDayIndex = 0; - string profitPerDayJSON = ""; - - if (PTData.SellLog.Count > 0) - { - DateTime minSellLogDate = PTData.SellLog.OrderBy(sl => sl.SoldDate).First().SoldDate.Date; - DateTime graphStartDate = DateTime.UtcNow.Date.AddDays(-30); - if (minSellLogDate > graphStartDate) + StringBuilder profitPerDayJSON = new StringBuilder(); + + if (PTData.DailyStats.Count > 0) { - graphStartDate = minSellLogDate; + DateTime endDate = DateTime.UtcNow.Date; + DateTime startDate = endDate.AddDays(-30); + + for (DateTime date = startDate; date <= endDate; date = date.AddDays(1)) + { + if (profitPerDayJSON.Length > 0) + { + profitPerDayJSON.Append(",\n"); + } + DailyStatsData dailyStats = PTData.DailyStats.Find(ds => DateTime.ParseExact(ds.Date, "d-M-yyyy", CultureInfo.InvariantCulture) == date); + double profitFiat = dailyStats != null ? Math.Round(dailyStats.TotalProfitCurrency,2) : 0; + profitPerDayJSON.Append("{x: new Date('" + date.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"); + } + ProfitChartDataJSON = "[{key: 'Profit in " + PTData.Properties.Currency + "',color: '" + Constants.ChartLineColors[1] + "',values: [" + profitPerDayJSON.ToString() + "]}]"; } - for (DateTime salesDate = graphStartDate; salesDate <= DateTime.UtcNow.Date; salesDate = salesDate.AddDays(1)) - { - if (tradeDayIndex > 0) - { - profitPerDayJSON += ",\n"; - } - 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); - 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++; - } - ProfitChartDataJSON = "["; - ProfitChartDataJSON += "{"; - ProfitChartDataJSON += "key: 'Profit in " + Summary.MainFiatCurrency + "',"; - ProfitChartDataJSON += "color: '" + Constants.ChartLineColors[1] + "',"; - ProfitChartDataJSON += "values: [" + profitPerDayJSON + "]"; - ProfitChartDataJSON += "}"; - ProfitChartDataJSON += "]"; - } } + private void BuildAssetDistributionData() { // the per PT-Eelroy, the PT API doesn't provide these values when using leverage, so they are calculated here to cover either case. @@ -171,9 +171,9 @@ namespace Monitor.Pages bool isSellStrategyTrue = false; bool isTrailingSellActive = false; - foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog) - { - string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive); + foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog) + { + string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive); // Aggregate totals double leverage = dcaLogEntry.Leverage; 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 beb9ffe..47fc107 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,6 @@ "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 - "StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "TimezoneOffset": "+0:00", // Your timezone offset from UTC time //"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor "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 diff --git a/_Development/DevSettings/settings.general.json b/_Development/DevSettings/settings.general.json index beb9ffe..47fc107 100644 --- a/_Development/DevSettings/settings.general.json +++ b/_Development/DevSettings/settings.general.json @@ -10,7 +10,6 @@ "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 - "StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "TimezoneOffset": "+0:00", // Your timezone offset from UTC time //"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor "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