LIVE TCV / TV Layout / Timezone / Cosmetics

This commit is contained in:
HojouFotytu 2024-01-24 03:05:28 +09:00
parent e474033d9c
commit 6aa6928376
25 changed files with 376 additions and 521 deletions

View File

@ -42,7 +42,7 @@ namespace Core.Main.DataObjects.PTMagicData
public int FloodProtectionMinutes { get; set; } = 15; public int FloodProtectionMinutes { get; set; } = 15;
public string Exchange { get; set; } public string Exchange { get; set; }
public string InstanceName { get; set; } = "PT Magic"; 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 CoinMarketCapAPIKey { get; set; }
//public string FreeCurrencyConverterAPIKey { get; set; } //public string FreeCurrencyConverterAPIKey { get; set; }
} }
@ -55,13 +55,13 @@ namespace Core.Main.DataObjects.PTMagicData
public bool OpenBrowserOnStart { get; set; } = false; public bool OpenBrowserOnStart { get; set; } = false;
public int Port { get; set; } = 5000; public int Port { get; set; } = 5000;
public string AnalyzerChart { get; set; } = ""; public string AnalyzerChart { get; set; } = "";
public int LiveTCVTimeframeMinutes { get; set; } = 60;
public int GraphIntervalMinutes { get; set; } = 60; public int GraphIntervalMinutes { get; set; } = 60;
public int GraphMaxTimeframeHours { get; set; } = 24; public int GraphMaxTimeframeHours { get; set; } = 24;
public int ProfitsMaxTimeframeDays { get; set; } = 60; public int ProfitsMaxTimeframeDays { get; set; } = 60;
public int RefreshSeconds { get; set; } = 30; public int RefreshSeconds { get; set; } = 30;
public int BagAnalyzerRefreshSeconds { get; set; } = 5; public int BagAnalyzerRefreshSeconds { get; set; } = 5;
public int BuyAnalyzerRefreshSeconds { get; set; } = 5; public int BuyAnalyzerRefreshSeconds { get; set; } = 5;
//public int MaxSalesRecords { get; set; } = 99999;
public int MaxTopMarkets { get; set; } = 20; public int MaxTopMarkets { get; set; } = 20;
public int MaxDailySummaries { get; set; } = 10; public int MaxDailySummaries { get; set; } = 10;
public int MaxMonthlySummaries { 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 MaxDCAPairs { get; set; } = 24;
public int MaxSettingsLogEntries { get; set; } = 20; public int MaxSettingsLogEntries { get; set; } = 20;
public string LinkPlatform { get; set; } = "TradingView"; public string LinkPlatform { get; set; } = "TradingView";
public string TVCustomLayout { get; set; } = "";
public string DefaultDCAMode { get; set; } = "Simple"; public string DefaultDCAMode { get; set; } = "Simple";
public string TvStudyA { get; set; } = ""; public string TvStudyA { get; set; } = "";
public string TvStudyB { get; set; } = ""; public string TvStudyB { get; set; } = "";
@ -572,5 +573,7 @@ namespace Core.Main.DataObjects.PTMagicData
public string Market { get; set; } public string Market { get; set; }
public string TotalCurrentValue { get; set; } public string TotalCurrentValue { get; set; }
public string TimeZoneOffset { get; set; } public string TimeZoneOffset { get; set; }
public string ExchangeURL { get; set; }
public string PTVersion { get; set; }
} }
} }

View File

@ -82,8 +82,11 @@ namespace Core.Main.DataObjects
{ {
if (!_offsetTimeSpan.HasValue) if (!_offsetTimeSpan.HasValue)
{ {
// Get offset for settings. // Ensure Misc is populated
_offsetTimeSpan = TimeSpan.Parse(_systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); var misc = this.Misc;
// Get offset from Misc
_offsetTimeSpan = TimeSpan.Parse(misc.TimeZoneOffset);
} }
return _offsetTimeSpan.Value; return _offsetTimeSpan.Value;
@ -133,6 +136,8 @@ namespace Core.Main.DataObjects
StartBalance = PTData.startBalance, StartBalance = PTData.startBalance,
TotalCurrentValue = PTData.totalCurrentValue, TotalCurrentValue = PTData.totalCurrentValue,
TimeZoneOffset = PTData.timeZoneOffset, TimeZoneOffset = PTData.timeZoneOffset,
ExchangeURL = PTData.exchangeUrl,
PTVersion = PTData.version,
}; };
} }
public List<DailyStatsData> DailyStats public List<DailyStatsData> DailyStats
@ -585,57 +590,6 @@ namespace Core.Main.DataObjects
Order = monthlyStatsDataJson["order"], Order = monthlyStatsDataJson["order"],
}; };
} }
// public List<SellLogData> 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<DCALogData> DCALog public List<DCALogData> DCALog
{ {
@ -677,26 +631,30 @@ namespace Core.Main.DataObjects
return _dcaLog; return _dcaLog;
} }
} }
public List<BuyLogData> BuyLog public List<BuyLogData> BuyLog
{ {
get get
{ {
if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh)) if (_systemConfiguration.GeneralSettings.Monitor.MaxDashboardBuyEntries == 0)
{
lock (_buyLock)
{ {
// Thread double locking return _buyLog;
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; 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;
} }
} }

View File

@ -1,6 +1,4 @@
using System; using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; 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 = "#"; string result = "#";
if (tvCustomLayout.Length > 0)
{
tvCustomLayout += "/";
}
if (platform.Equals("TradingView")) if (platform.Equals("TradingView"))
{ {
if (exchange.Equals("binancefutures", StringComparison.InvariantCultureIgnoreCase)) 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 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 else

View File

@ -63,21 +63,8 @@
}; };
var loadDashboardBottom = function () { var loadDashboardBottom = function () {
//destroy all d3 svg graph to avoid memory leak // Clear existing interval to stop multiple attempts to load at the same time.
setTimeout(function() if (intervalDashboardBottom != null) {
{
$(".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)
{
clearInterval(intervalDashboardBottom); clearInterval(intervalDashboardBottom);
} }
@ -92,6 +79,17 @@
window.location.replace("@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)Login"); window.location.replace("@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)Login");
} else { } else {
errCountIndex["DashboardBottom"] = 0; 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. // Reinstate the interval.

View File

@ -69,7 +69,7 @@
<tr> <tr>
<th> <th>
@if (!lastMarket.Equals(smsSummary.Market)) { @if (!lastMarket.Equals(smsSummary.Market)) {
<a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, smsSummary.Market, Model.Summary.MainMarket)" target="_blank">@smsSummary.Market</a> <a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, smsSummary.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@smsSummary.Market</a>
} }
</th> </th>
<td> <td>

View File

@ -271,9 +271,9 @@ else
} }
</th> </th>
@if (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { @if (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) {
<th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket)" target="_blank">@market</a></th> <th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@market</a></th>
} else { } else {
<th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket)" target="_blank">@market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th> <th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th>
} }
<td class="text-right">@mps.LatestPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainMarket</td> <td class="text-right">@mps.LatestPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainMarket</td>
<td class="text-right">@Math.Round(mps.Latest24hVolume, 0).ToString("#,#0", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainMarket</td> <td class="text-right">@Math.Round(mps.Latest24hVolume, 0).ToString("#,#0", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainMarket</td>
@ -336,9 +336,9 @@ else
} }
</th> </th>
@if (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { @if (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) {
<th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket)" target="_blank">@market</a></th> <th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@market</a></th>
} else { } else {
<th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket)" target="_blank">@market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th> <th><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th>
} }
<td class="text-right">@mps.LatestPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td> <td class="text-right">@mps.LatestPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right">@Math.Round(mps.Latest24hVolume, 0).ToString("#,#0", new System.Globalization.CultureInfo("en-US"))</td> <td class="text-right">@Math.Round(mps.Latest24hVolume, 0).ToString("#,#0", new System.Globalization.CultureInfo("en-US"))</td>

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Core.Main; using Core.Main;
using Core.Helper; using Core.Helper;
using Core.Main.DataObjects;
using Core.Main.DataObjects.PTMagicData; using Core.Main.DataObjects.PTMagicData;
using System.Globalization; using System.Globalization;
@ -11,6 +12,8 @@ namespace Monitor.Pages
public class MarketAnalyzerModel : _Internal.BasePageModelSecure public class MarketAnalyzerModel : _Internal.BasePageModelSecure
{ {
public List<MarketTrend> MarketTrends { get; set; } = new List<MarketTrend>(); public List<MarketTrend> MarketTrends { get; set; } = new List<MarketTrend>();
public ProfitTrailerData PTData = null;
public MiscData MiscData { get; set; }
public string TrendChartDataJSON = ""; public string TrendChartDataJSON = "";
public double DataHours { get; set; } public double DataHours { get; set; }
@ -22,7 +25,8 @@ namespace Monitor.Pages
private void BindData() 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(); MarketTrends = PTMagicConfiguration.AnalyzerSettings.MarketAnalyzer.MarketTrends.OrderBy(mt => mt.TrendMinutes).ThenByDescending(mt => mt.Platform).ToList();
BuildMarketTrendChartData(); BuildMarketTrendChartData();
@ -56,8 +60,8 @@ namespace Monitor.Pages
// Get trend ticks for chart // Get trend ticks for chart
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {

View File

@ -329,7 +329,7 @@
double profitFiat = Math.Round(profit * Model.MiscData.FiatConversionRate, 0); double profitFiat = Math.Round(profit * Model.MiscData.FiatConversionRate, 0);
<tr> <tr>
<td>@rank</td> <td>@rank</td>
<td><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, coin, Model.PTData.Misc.Market)" target="_blank">@coin</a></td> <td><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, coin, Model.PTData.Misc.Market, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@coin</a></td>
<td class="text-right text-autocolor-saw">@profit</td> <td class="text-right text-autocolor-saw">@profit</td>
<td class="text-right">@sales</td> <td class="text-right">@sales</td>
<td class="text-right text-autocolor-saw">@avg </td> <td class="text-right text-autocolor-saw">@avg </td>

View File

@ -54,7 +54,7 @@ namespace Monitor.Pages
DailyStats = this.PTData.DailyStats; DailyStats = this.PTData.DailyStats;
// Convert local offset time to UTC // 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); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
BuildSalesChartData(); BuildSalesChartData();
@ -71,8 +71,8 @@ namespace Monitor.Pages
{ {
// Get timezone offset // Get timezone offset
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {
@ -129,8 +129,8 @@ namespace Monitor.Pages
{ {
// Get timezone offset // Get timezone offset
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {
@ -190,8 +190,8 @@ namespace Monitor.Pages
{ {
// Get timezone offset // Get timezone offset
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {
@ -301,8 +301,8 @@ namespace Monitor.Pages
{ {
// Get timezone offset // Get timezone offset
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {

View File

@ -117,12 +117,12 @@
</div> </div>
</div> </div>
<div class="form-group row"> @* <div class="form-group row">
<label class="col-md-4 col-form-label">Timezone Offset <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The time difference between your current location and UTC time. Examples: +7:00, -3:00"></i></label> <label class="col-md-4 col-form-label">Timezone Offset <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The time difference between your current location and UTC time. Examples: +7:00, -3:00"></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Application_TimezoneOffset" value="@Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset"> <input type="text" class="form-control" name="Application_TimezoneOffset" value="@Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset">
</div> </div>
</div> </div> *@
@* <div class="form-group row"> @* <div class="form-group row">
<label class="col-md-4 col-form-label">Main Fiat Currency <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This is the local currency you want PTM to use when showing your sales and account value in fiat."></i></label> <label class="col-md-4 col-form-label">Main Fiat Currency <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This is the local currency you want PTM to use when showing your sales and account value in fiat."></i></label>
@ -196,42 +196,48 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Market Trend Graph Interval Minutes <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The time interval for the market trend graph (Dashboard and Sales Analyzer) between data points. Very small intervals on large timeframe graphs can significantly impact performance."></i></label> <label class="col-md-4 col-form-label">Live TCV Timeframe (Minutes) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The total timeframe for the Live TCV chart on the Dashboard. Very large timeframes can significantly impact performance."></i></label>
<div class="col-md-8">
<input type="text" class="form-control" name="Monitor_LiveTCVTimeframeMinutes" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.LiveTCVTimeframeMinutes.ToString(new System.Globalization.CultureInfo("en-US"))">
</div>
</div>
<div class="form-group row">
<label class="col-md-4 col-form-label">Market Trend Chart Interval (Minutes) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The time interval for the market trend graph (Dashboard and Sales Analyzer) between data points. Very small intervals on large timeframe graphs can significantly impact performance."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_GraphIntervalMinutes" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_GraphIntervalMinutes" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes.ToString(new System.Globalization.CultureInfo("en-US"))">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Market Trend Graph Max Timeframe <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This defines the total timeframe for the market trends graph (Dashboard and Sales Analyzer) in hours. Large timeframe graphs can significantly impact performance."></i></label> <label class="col-md-4 col-form-label">Market Trend Chart Max Timeframe (Hours) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This defines the total timeframe for the market trends graph (Dashboard and Sales Analyzer) in hours. Large timeframe graphs can significantly impact performance."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_GraphMaxTimeframeHours" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_GraphMaxTimeframeHours" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours.ToString(new System.Globalization.CultureInfo("en-US"))">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Daily Profit Graph Max Timeframe <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This defines the total timeframe for the daily profits graph on the dashboard in days. Large timeframes can significantly impact performance."></i></label> <label class="col-md-4 col-form-label">Daily Profit Graph Max Timeframe (Days) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This defines the total timeframe for the daily profits graph on the dashboard in days. Large timeframes can significantly impact performance."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_ProfitsMaxTimeframeDays" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_ProfitsMaxTimeframeDays" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays.ToString(new System.Globalization.CultureInfo("en-US"))">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Dashboard Bottom Refresh <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval in seconds, of the charts and graphs on then main page."></i></label> <label class="col-md-4 col-form-label">Dashboard Bottom Refresh (Seconds) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval in seconds, of the charts and graphs on then main page."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_RefreshSeconds" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_RefreshSeconds" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds.ToString(new System.Globalization.CultureInfo("en-US"))">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Bag AnalyzerRefresh Seconds <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval of your monitor bag analyzer page."></i></label> <label class="col-md-4 col-form-label">Bag AnalyzerRefresh (Seconds) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval of your monitor bag analyzer page."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_BagAnalyzerRefreshSeconds" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_BagAnalyzerRefreshSeconds" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds.ToString(new System.Globalization.CultureInfo("en-US"))">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Buy AnalyzerRefresh Seconds <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval of your monitor buy analyzer page."></i></label> <label class="col-md-4 col-form-label">Buy AnalyzerRefresh (Seconds) <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval of your monitor buy analyzer page."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_BuyAnalyzerRefreshSeconds" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_BuyAnalyzerRefreshSeconds" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds.ToString(new System.Globalization.CultureInfo("en-US"))">
</div> </div>
@ -247,12 +253,12 @@
</div> </div>
</div> </div>
@* <div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Max Sales Records<i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The number of sales records PTMagic pulls from Profit Trailer. Changes require a Monitor Restart."></i></label> <label class="col-md-4 col-form-label">TV Custom Chart <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="If TradingView is selected above, you can use the custom layout code found in your TV URL - ex. AGrfHNiI."></i></label>
<div class="col-md-8"> <div class="col-md-8">
<input type="text" class="form-control" name="Monitor_MaxSalesRecords" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxSalesRecords.ToString(new System.Globalization.CultureInfo("en-US"))"> <input type="text" class="form-control" name="Monitor_TVCustomLayout" value="@Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout">
</div> </div>
</div> *@ </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Max Top Markets <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The amount of top markets being show in your Sales Analyzer."></i></label> <label class="col-md-4 col-form-label">Max Top Markets <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The amount of top markets being show in your Sales Analyzer."></i></label>

View File

@ -27,30 +27,6 @@ namespace Monitor.Pages
return result; return result;
} }
public string GetTimezoneSelection()
{
string result = "";
List<string> tzOffsetList = new List<string>();
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 += "<option" + selected + ">" + offsetString + "</option>\n";
tzOffsetList.Add(offsetString);
}
}
return result;
}
public void OnGet() public void OnGet()
{ {
base.Init(); base.Init();
@ -78,7 +54,7 @@ namespace Monitor.Pages
PTMagicConfiguration.GeneralSettings.Application.Exchange = HttpContext.Request.Form["Application_Exchange"]; PTMagicConfiguration.GeneralSettings.Application.Exchange = HttpContext.Request.Form["Application_Exchange"];
PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL = HttpContext.Request.Form["Application_ProfitTrailerMonitorURL"]; PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL = HttpContext.Request.Form["Application_ProfitTrailerMonitorURL"];
PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken = HttpContext.Request.Form["Application_ProfitTrailerServerAPIToken"]; 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.MainFiatCurrency = HttpContext.Request.Form["Application_MainFiatCurrency"];
PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes = SystemHelper.TextToInteger(HttpContext.Request.Form["Application_FloodProtectionMinutes"], PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes); 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.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.OpenBrowserOnStart = HttpContext.Request.Form["Monitor_OpenBrowserOnStart"].Equals("on");
PTMagicConfiguration.GeneralSettings.Monitor.AnalyzerChart = HttpContext.Request.Form["Monitor_AnalyzerChart"]; PTMagicConfiguration.GeneralSettings.Monitor.AnalyzerChart = HttpContext.Request.Form["Monitor_AnalyzerChart"];
PTMagicConfiguration.GeneralSettings.Monitor.Port = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_Port"], PTMagicConfiguration.GeneralSettings.Monitor.Port); PTMagicConfiguration.GeneralSettings.Monitor.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.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.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.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.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.BuyAnalyzerRefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_BuyAnalyzerRefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds);
PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform = HttpContext.Request.Form["Monitor_LinkPlatform"]; 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.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.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); PTMagicConfiguration.GeneralSettings.Monitor.MaxMonthlySummaries = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_MaxMonthlySummaries"], PTMagicConfiguration.GeneralSettings.Monitor.MaxMonthlySummaries);

View File

@ -116,13 +116,8 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="card-box"> <div class="card-box">
<h4 class="m-t-0 header-title">Global Settings Log</h4> <h4 class="m-t-0 header-title">Global Settings Log</h4>
<table class="table table-striped table-sm"> <table class="table table-striped table-sm">
@ -136,7 +131,7 @@
</thead> </thead>
<tbody> <tbody>
@foreach (Core.Main.DataObjects.PTMagicData.GlobalSettingSummary gss in Model.Summary.GlobalSettingSummary.OrderByDescending(g => g.SwitchDateTime).Take(Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxSettingsLogEntries)) { @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; DateTimeOffset settingActivationTime = gss.SwitchDateTime;
settingActivationTime = settingActivationTime.ToOffset(offsetTimeSpan); settingActivationTime = settingActivationTime.ToOffset(offsetTimeSpan);

View File

@ -4,6 +4,7 @@ using System.Linq;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Core.Main; using Core.Main;
using Core.Helper; using Core.Helper;
using Core.Main.DataObjects;
using Core.Main.DataObjects.PTMagicData; using Core.Main.DataObjects.PTMagicData;
namespace Monitor.Pages namespace Monitor.Pages
@ -14,6 +15,8 @@ namespace Monitor.Pages
public string SettingsDistribution24hChartDataJSON = ""; public string SettingsDistribution24hChartDataJSON = "";
public string SettingsDistribution3dChartDataJSON = ""; public string SettingsDistribution3dChartDataJSON = "";
private Dictionary<string, string> settingsChartColors = new Dictionary<string, string>(); private Dictionary<string, string> settingsChartColors = new Dictionary<string, string>();
public ProfitTrailerData PTData = null;
public MiscData MiscData { get; set; }
public void OnGet() public void OnGet()
{ {
@ -24,6 +27,8 @@ namespace Monitor.Pages
private void BindData() private void BindData()
{ {
PTData = this.PtDataObject;
MiscData = this.PTData.Misc;
BuildMarketsWithSingleSettings(); BuildMarketsWithSingleSettings();
BuildChartColors(); BuildChartColors();
Build24hChartData(); Build24hChartData();

View File

@ -1,174 +0,0 @@
@page
@model TransactionsModel
@{
ViewData["Title"] = "";
}
@section Styles {
<link href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/tablesaw/css/tablesaw.css" rel="stylesheet" type="text/css" />
<link href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/bootstrap-datepicker/css/bootstrap-datepicker.min.css" rel="stylesheet">
<link href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/clockpicker/css/bootstrap-clockpicker.min.css" rel="stylesheet">
}
<div class="row">
<div class="col-md-12">
<div class="card-box">
<h4 class="m-t-0 header-title">Transactions</h4>
<p>
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.
</p>
</div>
</div>
</div>
<form class="form-horizontal m-t-20" method="post">
<div class="row">
<div class="col-md-12">
<div class="card-box">
<h4 class="m-t-0 header-title">New Transaction</h4>
<div class="form-group row">
<label class="col-md-4 col-form-label">Amount <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The amount of your transaction. Positive numbers for deposits and negative numbers for withdrawals."></i></label>
<div class="col-md-8">
<input type="text" class="form-control" name="Transaction_Amount">
</div>
</div>
<div class="form-group row">
<label class="col-md-4 col-form-label">Date <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The date of your transaction."></i></label>
<div class="col-md-8">
<div class="input-group">
<input type="text" class="form-control" placeholder="mm/dd/yyyy" id="datepicker-autoclose" name="Transaction_Date">
<span class="input-group-addon bg-custom b-0"><i class="md md-event-note text-dark"></i></span>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-4 col-form-label">Time <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The time of your transaction."></i></label>
<div class="col-md-8">
<div class="input-group clockpicker m-b-20" data-placement="top" data-align="top" data-autoclose="true">
<input type="text" class="form-control" name="Transaction_Time">
<span class="input-group-addon"> <span class="md md-access-time"></span> </span>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-4 col-form-label"></label>
<div class="col-md-8">
<button class="btn btn-ptmagic btn-block text-uppercase waves-effect waves-light" type="submit">
Save Transaction
</button>
</div>
</div>
</div>
</div>
</div>
@if (!Model.ValidationMessage.Equals("")) {
<div class="row">
<div class="col-md-12">
<div class="card-box text-danger">
@Model.ValidationMessage
</div>
</div>
</div>
}
</form>
<div class="row">
<div class="col-md-12">
<div class="card-box">
<h4 class="m-t-0 header-title">Your Transactions</h4>
@if (Model.TransactionData.Transactions.Count > 0) {
<table class="tablesaw table m-b-0" data-tablesaw-sortable data-tablesaw-sortable-switch>
<thead>
<tr>
<th></th>
<th scope="col" data-tablesaw-sortable-col data-tablesaw-sortable-default-col>Time</th>
<th scope="col" data-tablesaw-sortable-col class="text-right">Amount</th>
<th scope="col" data-tablesaw-sortable-col>Type</th>
</tr>
</thead>
<tbody>
@foreach (Core.Main.DataObjects.PTMagicData.Transaction transaction in Model.TransactionData.Transactions) {
<tr>
<td style="width:20px;"><a href="#" class="btn-remove" data-transactionguid="@transaction.GUID"><i class="fa fa-remove text-danger"></i></a></td>
<td>@transaction.GetLocalDateTime(Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset).ToShortDateString() @transaction.GetLocalDateTime(Model.PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset).ToShortTimeString()</td>
<td class="text-right text-autocolor">@transaction.Amount.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
@if (transaction.Amount > 0) {
<td class="text-success">Deposit</td>
} else {
<td class="text-danger">Withdrawal</td>
}
</tr>
}
</tbody>
</table>
} else {
<p>No transactions found.</p>
}
</div>
</div>
</div>
@section Scripts {
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/tablesaw/js/tablesaw.js"></script>
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/tablesaw/js/tablesaw-init.js"></script>
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script>
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/clockpicker/js/bootstrap-clockpicker.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
$('.text-autocolor').autocolor(false);
jQuery('#datepicker-autoclose').datepicker({
weekStart: 1,
autoclose: true,
todayHighlight: true
});
$('.clockpicker').clockpicker({
donetext: 'Done'
});
@if (!Model.NotifyType.Equals("") && !Model.NotifyHeadline.Equals("") && !Model.NotifyMessage.Equals("")) {
<text>
$.Notification.notify('@Model.NotifyType', 'top left', '@Model.NotifyHeadline', '@Model.NotifyMessage');
</text>
}
$('.btn-remove').click(function () {
var tGuid = $(this).data('transactionguid');
var postData = { Transaction_GUID: tGuid };
$.ajax({
type: 'POST',
url: "@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)_post/RemoveTransaction",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(postData),
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (data) {
$.Notification.notify('success', 'top left', 'Transaction removed!', 'Transaction "' + tGuid + '" was successfully removed.');
window.location = window.location.href;
},
error: function (jqxhr, errorText, thrownError) {
$.Notification.notify('error', 'top left', 'Error removing transaction "' + tGuid + '"!', 'Error message: ' + errorText);
}
});
return false;
});
});
</script>
}

View File

@ -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";
}
}
}
}
}

View File

@ -103,7 +103,7 @@
<div class="tradingview-widget-container"> <div class="tradingview-widget-container">
<div id="tradingview_6aa22" style="height:600px;"></div> <div id="tradingview_6aa22" style="height:600px;"></div>
<div class="tradingview-widget-copyright"> <div class="tradingview-widget-copyright">
<a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, Model.DCAMarket, Model.Summary.MainMarket)" rel="noopener" target="_blank"> <a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, Model.DCAMarket, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" rel="noopener" target="_blank">
<span class="blue-text">@Model.DCAMarket</span> <span class="blue-text">chart</span> by TradingView</a> <span class="blue-text">@Model.DCAMarket</span> <span class="blue-text">chart</span> by TradingView</a>
</div> </div>
</div> </div>

View File

@ -10,6 +10,7 @@ using Core.MarketAnalyzer;
namespace Monitor.Pages { namespace Monitor.Pages {
public class BagDetailsModel : _Internal.BasePageModelSecure { public class BagDetailsModel : _Internal.BasePageModelSecure {
public ProfitTrailerData PTData = null; public ProfitTrailerData PTData = null;
public MiscData MiscData = null;
public string DCAMarket = ""; public string DCAMarket = "";
public DCALogData DCALogData = null; public DCALogData DCALogData = null;
public DateTimeOffset DateTimeNow = Constants.confMinDate; public DateTimeOffset DateTimeNow = Constants.confMinDate;
@ -23,13 +24,12 @@ namespace Monitor.Pages {
private void BindData() { private void BindData() {
DCAMarket = GetStringParameter("m", ""); DCAMarket = GetStringParameter("m", "");
PTData = this.PtDataObject; PTData = this.PtDataObject;
MiscData = this.PTData.Misc;
DCALogData = PTData.DCALog.Find(d => d.Market == DCAMarket); DCALogData = PTData.DCALog.Find(d => d.Market == DCAMarket);
// Convert local offset time to UTC // 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); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
} }
} }

View File

@ -84,9 +84,9 @@
<tr @(lostValue ? "class=errorRow" : "" ) > <tr @(lostValue ? "class=errorRow" : "" ) >
// Market // Market
@if (mps != null && (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)) { @if (mps != null && (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)) {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@dcaLogEntry.Market</a></th> <th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@dcaLogEntry.Market</a></th>
} else { } else {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@dcaLogEntry.Market</a> <th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@dcaLogEntry.Market</a>
<i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>">
</i> </i>
</th> </th>

View File

@ -37,9 +37,9 @@
string triggerValueText = Core.ProfitTrailer.StrategyHelper.GetTriggerValueText(Model.Summary, buyLogEntry.BuyStrategies, buyLogEntry.BuyStrategy, buyLogEntry.BBTrigger, buyLogEntry.TriggerValue, 0, true); string triggerValueText = Core.ProfitTrailer.StrategyHelper.GetTriggerValueText(Model.Summary, buyLogEntry.BuyStrategies, buyLogEntry.BuyStrategy, buyLogEntry.BBTrigger, buyLogEntry.TriggerValue, 0, true);
<tr> <tr>
@if (mps != null && (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)) { @if (mps != null && (mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)) {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a></th> <th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@buyLogEntry.Market</a></th>
} else { } else {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th> <th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@buyLogEntry.Market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th>
} }
<td class="text-autocolor">@buyLogEntry.PercChange.ToString("#,#0.00")%</td> <td class="text-autocolor">@buyLogEntry.PercChange.ToString("#,#0.00")%</td>
@if (buyDisabled) { @if (buyDisabled) {

View File

@ -10,7 +10,48 @@
} }
<div class="row"> <div class="row">
<div class="col-md-5 px-1">
<div class="col-md-3 px-1">
<div class="card-box px-1" style="height:240px;">
<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"
title="All charts set to refresh every @Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds seconds in your general settings."></div>
@{
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"));
}
}
<div id="AssetDistribution" class="container" style="height: 100%; width: 100%;">
<div class="text-center">
<span data-toggle="tooltip" data-placement="top" title="Total current account value">TCV: <text class="text-autocolor">@totalCurrentValueString @Model.Summary.MainMarket </text> </span>
</div>
<div class="text-center">
<small>
<span data-toggle="tooltip" data-placement="top" title="Starting balance from PTM settings">Start: <text class="text-autocolor">@Model.MiscData.StartBalance </text></span>
<span data-toggle="tooltip" data-placement="top" title="TCV gain on starting balance">&emsp; Gain: <text class="text-autocolor">@Math.Round(((Model.totalCurrentValue - Model.MiscData.StartBalance) / Model.MiscData.StartBalance) * 100, 2)%</text></span>
</small>
</div>
<svg style="height:100%;width:100%"></svg>
</div>
</div>
</div>
<div class="col-md-9">
<div class="card-box px-2" style="height:240px;">
<h4 class="m-t-0 header-title"><b>Live TCV Trend </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="Data is added while the monitor is running. Currently set to show the past @Model.PTMagicConfiguration.GeneralSettings.Monitor.LiveTCVTimeframeMinutes minutes in your monitor settings."></i>
@if (!Model.TotalCurrentValueLiveChartDataJSON.Equals("")) {
<div class="TCVLive-chart">
<svg style="height:220px;width:100%"></svg>
</div>
} else {
<p>Unable to load graph, no sales data found.</p>
}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 px-1">
<div class="card-box px-2" style="height:340px;"> <div class="card-box px-2" style="height:340px;">
<h4 class="m-t-0 m-b-20 header-title" style="display: inline;"><b>Market Trend History </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Math.Round(Model.DataHours, 1) hours of data available. Currently set to show @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours hours at @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes intervals, in general settings."></i></h4> <h4 class="m-t-0 m-b-20 header-title" style="display: inline;"><b>Market Trend History </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Math.Round(Model.DataHours, 1) hours of data available. Currently set to show @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours hours at @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes intervals, in general settings."></i></h4>
@if (!Model.TrendChartDataJSON.Equals("")) { @if (!Model.TrendChartDataJSON.Equals("")) {
@ -23,37 +64,12 @@
</div> </div>
</div> </div>
<div class="col-md-3 px-1">
<div class="card-box px-3" style="height:340px;">
<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"
title="All charts set to refresh every @Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds seconds in your general settings."></div>
@{
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"));
}
}
<div id="AssetDistribution" class="container">
<div class="text-center">
<small>
<span data-toggle="tooltip" data-placement="top" title="Starting balance from PTM settings">Start: &nbsp; <text class="text-autocolor"> @Model.MiscData.StartBalance @Model.Summary.MainMarket </text></span>
<span data-toggle="tooltip" data-placement="top" title="TCV gain on starting balance"> &emsp; &emsp; Gain:&nbsp;<text class="text-autocolor">@Math.Round(((Model.totalCurrentValue - Model.MiscData.StartBalance) / Model.MiscData.StartBalance) * 100, 2)%</text></span>
</small>
</div>
<div class="text-center">
<span data-toggle="tooltip" data-placement="top" title="Total current account value">TCV: &nbsp; <text class="text-autocolor"> @totalCurrentValueString @Model.Summary.MainMarket </text> </span>
</div>
<div class="row px1">
<svg style="height:260px;width:100%"></svg>
</div>
</div>
</div>
</div>
<div class="col-md-4 px-1"> <div class="col-md-6 px-1">
@*<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>*@ @*<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>*@
<div class="card-box px-2" style="height:340px;"> <div class="card-box px-2" style="height:340px;">
<h4 class="m-t-0 m-b-20 header-title" style="display: inline;">Daily Profit <i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Model.ProfitDays days of data available. Currently Set to @Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays days in general settings."></i> <h4 class="m-t-0 m-b-20 header-title" style="display: inline;">Daily Profit <i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Model.PTData.DailyPNL.Count days of data available. Currently Set to @Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays days in general settings."></i>
@if (!Model.ProfitChartDataJSON.Equals("")) { @if (!Model.ProfitChartDataJSON.Equals("")) {
<div class="profit-chart"> <div class="profit-chart">
<svg style="height:300px;width:100%"></svg> <svg style="height:300px;width:100%"></svg>
@ -70,9 +86,9 @@
<div class="card-box px-3"> <div class="card-box px-3">
@* <div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeco;nds * 1000)" data-color="#aaa,#414d59"></div> @* <div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeco;nds * 1000)" data-color="#aaa,#414d59"></div>
<br> *@ <br> *@
<h4 class="m-t-0 m-b-20 header-title">Live Trends <h4 class="m-t-0 m-b-20 header-title">Live Market Trends
<i class="fa fa-info-circle text-muted" style="font-size small" data-toggle="tooltip" data-placement="top" title="Set to refresh every @Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds seconds in general settings."></i> <i class="fa fa-info-circle text-muted" style="font-size small" data-toggle="tooltip" data-placement="top" title="Set to refresh every @Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds seconds in general settings."></i>
<small class="pull-right" style="font-size: x-small"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)MarketAnalyzer">ANALYZER</a></small> <small class="pull-right" style="font-size: small"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)MarketAnalyzer">ANALYZER</a></small>
</h4> </h4>
<table class="table table-sm"> <table class="table table-sm">
<thead> <thead>
@ -302,18 +318,23 @@
.labelThreshold(.1) .labelThreshold(.1)
.labelType("percent") .labelType("percent")
.donut(true) .donut(true)
.donutRatio(0.3); .donutRatio(0.3)
.margin({top: 10, bottom: 10})
.showLegend(false); // Hide the legend
assetDistributionData = @Html.Raw(Model.AssetDistributionData); assetDistributionData = @Html.Raw(Model.AssetDistributionData);
d3.select("#AssetDistribution svg") d3.select("#AssetDistribution svg")
.style('height', '90%')
.style('width', '100%')
.datum(assetDistributionData) .datum(assetDistributionData)
.transition().duration(0) .transition().duration(0)
.call(assetDistributionChart); .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('.profit-chart').on('mouseleave', function() {
d3.select('.nvtooltip').style('opacity', 0); d3.select('.nvtooltip').style('opacity', 0);
}); });
d3.select('body').on('mousemove', function() { d3.select('body').on('mousemove', function() {
@ -455,3 +476,50 @@
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
}); });
</script> </script>
<script type="text/javascript">
(function ($) {
'use strict';
$('[role="tooltip"]').remove();
$('[data-toggle="tooltip"]').tooltip();
$('.text-autocolor').autocolor(false);
var TCVLiveChart; // Keep a reference to the chart
var TCVLiveData; // Keep a reference to the data
@if (!Model.TotalCurrentValueLiveChartDataJSON.Equals("")) {
<text>
nv.addGraph(function () {
TCVLiveChart = nv.models.lineChart();
TCVLiveChart.useInteractiveGuideline(true);
TCVLiveChart.xAxis.tickFormat(function (d) { return d3.time.format('%H:%M:%S')(new Date(d)); });
TCVLiveChart.yAxis.axisLabel('').tickFormat(d3.format(',.2f'));
TCVLiveData = @Html.Raw(Model.TotalCurrentValueLiveChartDataJSON);
d3.select('.TCVLive-chart svg')
.style('width', '100%')
.datum(TCVLiveData)
.transition().duration(0)
.call(TCVLiveChart);
// Add mouseleave, and mousemove event listeners to hide tooltip
d3.select('.TCVLive-chart').on('mouseleave', function() {
d3.select('.nvtooltip').style('opacity', 0);
});
d3.select('body').on('mousemove', function() {
var chartBounds = d3.select('.TCVLive-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(TCVLiveChart.update);
return TCVLiveChart;
});
</text>
}
})(jQuery);
</script>

View File

@ -26,6 +26,7 @@ namespace Monitor.Pages
public DateTimeOffset DateTimeNow = Constants.confMinDate; public DateTimeOffset DateTimeNow = Constants.confMinDate;
public string AssetDistributionData = ""; public string AssetDistributionData = "";
public double totalCurrentValue = 0; public double totalCurrentValue = 0;
public string TotalCurrentValueLiveChartDataJSON { get; set; }
public void OnGet() public void OnGet()
{ {
// Initialize Config // 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); 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 // 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); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
// Get last and current active setting // Get last and current active setting
@ -65,8 +66,109 @@ namespace Monitor.Pages
BuildMarketTrendChartData(); BuildMarketTrendChartData();
BuildAssetDistributionData(); BuildAssetDistributionData();
BuildProfitChartData(); 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<object> TotalCurrentValueLivePerIntervalList = new List<object>();
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() private void BuildMarketTrendChartData()
{ {
List<string> trendChartData = new List<string>(); List<string> trendChartData = new List<string>();
@ -95,8 +197,8 @@ namespace Monitor.Pages
// Get trend ticks for chart // Get trend ticks for chart
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {
@ -158,8 +260,8 @@ namespace Monitor.Pages
{ {
// Get timezone offset // Get timezone offset
TimeSpan offset; TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-"); bool isNegative = MiscData.TimeZoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-'); string offsetWithoutSign = MiscData.TimeZoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset)) if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{ {

View File

@ -3,13 +3,15 @@
@{ @{
Layout = null; Layout = null;
} }
@{
<div class="row"> bool sideBySide = true;
}
<div class="@(sideBySide ? "row" : "col-md-12")">
@if (Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxDashboardBuyEntries>0) @if (Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxDashboardBuyEntries>0)
{ {
<div class="col-md-6 px-1"> <div class="col-md px-1">
<div class="card-box px-2"> <div class="card-box px-2">
<h4 class="m-t-0 m-b-20 header-title"><b>Possible Buys (@Model.PTData.BuyLog.Count)</b><small id="buylist-refresh-icon"></small><small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)BuyAnalyzer">more</a></small></h4> <h4 class="m-t-0 m-b-20 header-title"><b>Possible Buys (@Model.PTData.BuyLog.Count)</b><small id="buylist-refresh-icon"><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="Set 'Max Dashboard Buy Entries' to zero in Monitor Settings, to hide this table."></i></small><small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)BuyAnalyzer">more</a></small></h4>
@if (Model.PTData.BuyLog.Count == 0) @if (Model.PTData.BuyLog.Count == 0)
{ {
<p>Your Profit Trailer did not find anything worth buying so far.</p> <p>Your Profit Trailer did not find anything worth buying so far.</p>
@ -19,11 +21,10 @@
<table class="table table-sm m-b-0"> <table class="table table-sm m-b-0">
<thead> <thead>
<tr> <tr>
<th>Market</th> <th><strong>Market </strong><i class="fa fa-info-circle text-muted" style="font-size: x-small" data-toggle="tooltip" data-placement="top" title="Market and 24h CHANGE"></i></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="24 Hour price trend">24H</th> <th><strong>Volume </strong><i class="fa fa-info-circle text-muted" style="font-size: x-small" data-toggle="tooltip" data-placement="top" title="24h VOLUME"></i></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="24 Hour trading volume">Volume</th> <th><strong>Ask </strong></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Current ask price for this market">Ask</th> <th><strong>Buy Strategies </strong></th>
<th>Buy Strategies</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -57,13 +58,21 @@
<tr> <tr>
@if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { @if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a></th> <th>
<span style="font-size: 1.3em;"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@buyLogEntry.Market</span>
<br><span class="text-autocolor">@Html.Raw((buyLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) % </span>
</th>
} else { } else {
<th class="align-top; text-nowrap"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market &nbsp;</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th> <th>
<div style="white-space: nowrap;">
<span style="font-size: 1.3em;"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@buyLogEntry.Market</a></span>
&nbsp;<i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i>
</div>
<span class="text-autocolor">@Html.Raw((buyLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) % </span>
</th>
} }
<td class="text-autocolor">@string.Format("{0}%", (buyLogEntry.PercChange * 100).ToString("#,#0.00"))</td> <td >@string.Format("{0}", (buyLogEntry.Volume24h).ToString())</td>
<td class="text">@string.Format("{0}", (buyLogEntry.Volume24h).ToString())</td> <td >@buyLogEntry.CurrentPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-left">@buyLogEntry.CurrentPrice.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
@if (buyDisabled) { @if (buyDisabled) {
<td>@Html.Raw(buyStrategyText)</td> <td>@Html.Raw(buyStrategyText)</td>
@ -85,7 +94,7 @@
<div class="col-md px-1"> <div class="col-md px-1">
<div class="card-box px-2"> <div class="card-box px-2">
<h4 class="m-t-0 m-b-20 header-title"><b>Pairs / DCA / Pending (@Model.PTData.DCALog.Count)</b><small id="baglist-refresh-icon"></small><small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)BagAnalyzer">more</a></small></h4> <h4 class="m-t-0 m-b-20 header-title"><b>Positions (@Model.PTData.DCALog.Count)</b><small id="baglist-refresh-icon"></small><small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)BagAnalyzer">more</a></small></h4>
@if (Model.PTData.DCALog.Count == 0) @if (Model.PTData.DCALog.Count == 0)
{ {
@ -94,16 +103,15 @@
else else
{ {
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-sm m-b-0"> <table class="table table-sm m-b-0 table-auto-width">
<thead> <thead>
<tr> <tr>
<th>Market</th> <th><strong>Market </strong><i class="fa fa-info-circle text-muted" style="font-size: x-small" data-toggle="tooltip" data-placement="top" title="Market and 24h CHANGE"></i></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="24 Hour Trend">24H</th> <th><strong>Cost </strong><i class="fa fa-info-circle text-muted" style="font-size: x-small" data-toggle="tooltip" data-placement="top" title="Total COST and TIME HELD"></i></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Total Buy Cost">Cost</th>
<th></th> <th></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Active Buy Strategies">DCA</th> <th><strong>DCA </strong></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Active Sell Strategies">Sell</th> <th><strong>Sell </strong></th>
<th class="text-left" data-toggle="tooltip" data-html="true" data-placement="top" title="Profit Target <br> Current Profit">Profit</th> <th><strong>Profit </strong><i class="fa fa-info-circle text-muted" style="font-size: x-small" data-toggle="tooltip" data-placement="top" title="Proft TARGET and CURRENT Profit"></i></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -142,7 +150,6 @@
if (dcaLogEntry.SellStrategies.Count > 0) { if (dcaLogEntry.SellStrategies.Count > 0) {
isSellStrategyTrue = (dcaLogEntry.SellStrategies.FindAll(ss => !ss.IsTrue).Count == 0); isSellStrategyTrue = (dcaLogEntry.SellStrategies.FindAll(ss => !ss.IsTrue).Count == 0);
} }
string leverage = ""; string leverage = "";
double leverageValue = 1; double leverageValue = 1;
string buyStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.BuyStrategies, dcaLogEntry.BuyStrategy, isBuyStrategyTrue, isTrailingBuyActive); string buyStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.BuyStrategies, dcaLogEntry.BuyStrategy, isBuyStrategyTrue, isTrailingBuyActive);
@ -154,55 +161,38 @@
// Profit percentage // Profit percentage
var profitPercentage = dcaLogEntry.ProfitPercent; 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 // Render the row
if (!sellStrategyText.Contains("PENDING-BUY"))
if (!sellStrategyText.Contains("PENDING-BUY"))
{ {
<tr @(lostValue ? "class=errorRow" : "") > <tr @(lostValue ? "class=errorRow" : "") >
<!-- Market --> <!-- Market -->
<td class="align-top; text-nowrap"> <td class="align-top; text-nowrap">
<b> <b>
@if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) @if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0)
{ {
<a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@dcaLogEntry.Market</a> <span style="font-size: 1.3em;"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@dcaLogEntry.Market</a></span>
} else } else
{ {
<a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@dcaLogEntry.Market &nbsp;</a><i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i> <span style="font-size: 1.3em;"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, dcaLogEntry.Market, Model.Summary.MainMarket, Model.PTMagicConfiguration.GeneralSettings.Monitor.TVCustomLayout)" target="_blank">@dcaLogEntry.Market &nbsp;</a></span><i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i>
} }
</b> </b>
<br> <br><span class="text-autocolor">@Html.Raw((dcaLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) %</span>
@bagAgeText
</td> </td>
<!-- 24hr change -->
<td class="text-autocolor">@Html.Raw((dcaLogEntry.PercChange * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))%</td>
<!-- Cost --> <!-- Cost -->
<td class="text-left">@Html.Raw(dcaLogEntry.TotalCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))</td> <td class="text-left">@Html.Raw(dcaLogEntry.TotalCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))<br><span class="text-highlight">@bagAgeText</span></td>
<!-- DCA Count --> <!-- DCA Count -->
<td class="text-right"> <td class="text-right">
@if (dcaEnabled) @if (dcaEnabled)
{ {
@if (dcaLogEntry.BoughtTimes > 0) if (dcaLogEntry.BoughtTimes > 0)
{ {
@dcaLogEntry.BoughtTimes; @dcaLogEntry.BoughtTimes;
} }
} else } else
{ {
<span data-toggle="tooltip" data-placement="top" title="DCA is disabled"><i class="fa fa-ban text-highlight"></i></span> <span data-toggle="tooltip" data-placement="top" title="DCA disabled"><i class="fa fa-ban text-highlight"></i></span>
} }
</td> </td>
<!-- DCA Strategy --> <!-- DCA Strategy -->
@ -234,7 +224,7 @@
double TargetGain = leverageValue * dcaLogEntry.TargetGainValue.Value; double TargetGain = leverageValue * dcaLogEntry.TargetGainValue.Value;
<td>@TargetGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))% <td>@TargetGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%
<br> <br>
<div class="text-autocolor">@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</div> <div class="text-autocolor">@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</div>
</td> </td>
} }
else else
@ -242,7 +232,7 @@
<td> <td>
<div class="text-left">None</div> <div class="text-left">None</div>
<br> <br>
<div class="text-autocolor">@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</div> <div class="text-autocolor">@profitPercentage.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</div>
</td> </td>
} }
@ -255,24 +245,22 @@
} }
<!-- Bag details --> <!-- Bag details -->
<td class="text-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)_get/BagDetails/?m=@dcaLogEntry.Market" data-remote="false" data-toggle="modal" data-target="#dca-chart"><i class="fa fa-plus-circle"></i></a></td> <td class="text-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)_get/BagDetails/?m=@dcaLogEntry.Market" data-remote="false" data-toggle="modal" data-target="#dca-chart"><i class="fa fa-plus-circle"></i></a></td>
</tr> </tr>
{ {
// Aggregate totals // Aggregate totals
double bagGain = (profitPercentage / 100) * dcaLogEntry.TotalCost; double bagGain = (profitPercentage / 100) * dcaLogEntry.TotalCost;
Model.TotalBagCost = Model.TotalBagCost + dcaLogEntry.TotalCost; Model.TotalBagCost = Model.TotalBagCost + dcaLogEntry.TotalCost;
Model.TotalBagGain = Model.TotalBagGain + bagGain; Model.TotalBagGain = Model.TotalBagGain + bagGain;
} }
} }
}
} <td style="font-size: 1.2em;"><strong>Totals:</strong></td>
<td>Totals:</td> <td style="font-size: 1.2em;"><strong>@Html.Raw(Model.TotalBagCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))</strong></td>
<td></td> <td></td>
<td>@Html.Raw(Model.TotalBagCost.ToString("#,#0.000000", new System.Globalization.CultureInfo("en-US")))</td> <td></td>
<td></td> <td></td>
<td></td> <td class="text-autocolor; font-size: 1.2em;"><strong>@Html.Raw((((Model.TotalBagGain) / Model.TotalBagCost) * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))) %</strong></td>
<td></td> <td></td>
<td class="text-autocolor">@Html.Raw((((Model.TotalBagGain) / Model.TotalBagCost) * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))%</td>
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -1,15 +1,16 @@
using System; using System;
using Core.Main; using Core.Main;
using Core.Main.DataObjects; using Core.Main.DataObjects;
using Core.Main.DataObjects.PTMagicData;
namespace Monitor.Pages { namespace Monitor.Pages {
public class DashboardTopModel : _Internal.BasePageModelSecureAJAX { public class DashboardTopModel : _Internal.BasePageModelSecureAJAX {
public ProfitTrailerData PTData = null; public ProfitTrailerData PTData = null;
public MiscData MiscData = null;
public DateTimeOffset DateTimeNow = Constants.confMinDate; public DateTimeOffset DateTimeNow = Constants.confMinDate;
public void OnGet() { public void OnGet() {
// Initialize Config // Initialize Config
base.Init(); base.Init();
BindData(); BindData();
} }
public double TotalBagCost = 0; public double TotalBagCost = 0;
@ -17,9 +18,9 @@ namespace Monitor.Pages {
public double TotalBagGain = 0; public double TotalBagGain = 0;
private void BindData() { private void BindData() {
PTData = this.PtDataObject; PTData = this.PtDataObject;
MiscData = this.PTData.Misc;
// Convert local offset time to UTC // 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); DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
} }
} }

View File

@ -10,7 +10,7 @@
"ProfitTrailerMonitorURLXtra": "", // URLs for additional bots you want PTM to update (optional - comma separated list) "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) "ProfitTrailerDefaultSettingName": "default", // Your Profit Trailer default setting name (needed to change your settings)
"Exchange": "Bittrex", // The exchange your are running Profit Trailer on "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 "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 "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 //"FreeCurrencyConverterAPIKey": "" // If "MainFiatCurrency" above is anything other than USD, you must obtain an API key from https://free.currencyconverterapi.com/free-api-key

View File

@ -10,7 +10,7 @@
"ProfitTrailerMonitorURLXtra": "", // URLs for additional bots you want PTM to update (optional - comma separated list) "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) "ProfitTrailerDefaultSettingName": "default", // Your Profit Trailer default setting name (needed to change your settings)
"Exchange": "Bittrex", // The exchange your are running Profit Trailer on "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 "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 "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 "CoinMarketCapAPIKey": "", //CoinMarketCap Api