More Dashboard Bottom Optimizations
This commit is contained in:
parent
28c12e6d5a
commit
16fada1443
|
@ -41,10 +41,8 @@ namespace Core.Main.DataObjects.PTMagicData
|
||||||
public string ProfitTrailerDefaultSettingName { get; set; } = "default";
|
public string ProfitTrailerDefaultSettingName { get; set; } = "default";
|
||||||
public int FloodProtectionMinutes { get; set; } = 15;
|
public int FloodProtectionMinutes { get; set; } = 15;
|
||||||
public string Exchange { get; set; }
|
public string Exchange { get; set; }
|
||||||
//public double StartBalance { get; set; } = 0;
|
|
||||||
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 MainFiatCurrency { get; set; } = "USD";
|
|
||||||
public string CoinMarketCapAPIKey { get; set; }
|
public string CoinMarketCapAPIKey { get; set; }
|
||||||
//public string FreeCurrencyConverterAPIKey { get; set; }
|
//public string FreeCurrencyConverterAPIKey { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -59,6 +57,7 @@ namespace Core.Main.DataObjects.PTMagicData
|
||||||
public string AnalyzerChart { get; set; } = "";
|
public string AnalyzerChart { get; set; } = "";
|
||||||
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 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;
|
||||||
|
@ -127,6 +126,7 @@ namespace Core.Main.DataObjects.PTMagicData
|
||||||
|
|
||||||
[DefaultValue("Market")]
|
[DefaultValue("Market")]
|
||||||
public string TrendCurrency { get; set; } = "Market";
|
public string TrendCurrency { get; set; } = "Market";
|
||||||
|
public string SplitCamelCaseName { get; set; }
|
||||||
|
|
||||||
[DefaultValue(0)]
|
[DefaultValue(0)]
|
||||||
public int MaxMarkets { get; set; } = 0;
|
public int MaxMarkets { get; set; } = 0;
|
||||||
|
@ -442,15 +442,6 @@ namespace Core.Main.DataObjects.PTMagicData
|
||||||
public double FundingTotal { get; set; }
|
public double FundingTotal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DailyStatsData
|
|
||||||
{
|
|
||||||
public string Date { get; set; }
|
|
||||||
public double TotalSales { get; set; }
|
|
||||||
public double TotalBuys { get; set; }
|
|
||||||
public double TotalProfitCurrency { get; set; }
|
|
||||||
public int Order { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DailyPNLData
|
public class DailyPNLData
|
||||||
{
|
{
|
||||||
public string Date { get; set; }
|
public string Date { get; set; }
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Core.Main.DataObjects.PTMagicData;
|
using Core.Main.DataObjects.PTMagicData;
|
||||||
|
|
||||||
|
@ -17,15 +18,25 @@ namespace Core.Main.DataObjects
|
||||||
private SummaryData _summary = null;
|
private SummaryData _summary = null;
|
||||||
private PropertiesData _properties = null;
|
private PropertiesData _properties = null;
|
||||||
private StatsData _stats = null;
|
private StatsData _stats = null;
|
||||||
private List<DailyStatsData> _dailyStats = new List<DailyStatsData>();
|
|
||||||
private List<DailyPNLData> _dailyPNL = new List<DailyPNLData>();
|
private List<DailyPNLData> _dailyPNL = new List<DailyPNLData>();
|
||||||
|
private decimal? _totalProfit = null;
|
||||||
|
public decimal? TotalProfit
|
||||||
|
{
|
||||||
|
get { return _totalProfit; }
|
||||||
|
set { _totalProfit = value; }
|
||||||
|
}
|
||||||
|
private decimal? _totalSales = null;
|
||||||
|
public decimal? TotalSales
|
||||||
|
{
|
||||||
|
get { return _totalSales; }
|
||||||
|
set { _totalSales = value; }
|
||||||
|
}
|
||||||
private List<SellLogData> _sellLog = new List<SellLogData>();
|
private List<SellLogData> _sellLog = new List<SellLogData>();
|
||||||
private List<DCALogData> _dcaLog = new List<DCALogData>();
|
private List<DCALogData> _dcaLog = new List<DCALogData>();
|
||||||
private List<BuyLogData> _buyLog = new List<BuyLogData>();
|
private List<BuyLogData> _buyLog = new List<BuyLogData>();
|
||||||
private string _ptmBasePath = "";
|
private string _ptmBasePath = "";
|
||||||
private PTMagicConfiguration _systemConfiguration = null;
|
private PTMagicConfiguration _systemConfiguration = null;
|
||||||
private TransactionData _transactionData = null;
|
private TransactionData _transactionData = null;
|
||||||
private DateTime _dailyStatsRefresh = DateTime.UtcNow;
|
|
||||||
private DateTime _dailyPNLRefresh = DateTime.UtcNow;
|
private DateTime _dailyPNLRefresh = DateTime.UtcNow;
|
||||||
private DateTime _statsRefresh = DateTime.UtcNow;
|
private DateTime _statsRefresh = DateTime.UtcNow;
|
||||||
private DateTime _buyLogRefresh = DateTime.UtcNow;
|
private DateTime _buyLogRefresh = DateTime.UtcNow;
|
||||||
|
@ -143,6 +154,28 @@ namespace Core.Main.DataObjects
|
||||||
BaseUrl = PTProperties.baseUrl
|
BaseUrl = PTProperties.baseUrl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// public StatsData Stats
|
||||||
|
// {
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// if (_stats == null || DateTime.UtcNow > _statsRefresh)
|
||||||
|
// {
|
||||||
|
// lock (_statsLock)
|
||||||
|
// {
|
||||||
|
// if (_stats == null || DateTime.UtcNow > _statsRefresh)
|
||||||
|
// {
|
||||||
|
// dynamic statsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
|
||||||
|
// JObject statsDataJObject = statsDataJson as JObject;
|
||||||
|
// JObject basicSection = (JObject)statsDataJObject["basic"];
|
||||||
|
// _stats = BuildStatsData(basicSection);
|
||||||
|
// _statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return _stats;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public StatsData Stats
|
public StatsData Stats
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -153,17 +186,29 @@ namespace Core.Main.DataObjects
|
||||||
{
|
{
|
||||||
if (_stats == null || DateTime.UtcNow > _statsRefresh)
|
if (_stats == null || DateTime.UtcNow > _statsRefresh)
|
||||||
{
|
{
|
||||||
dynamic statsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
|
using (var stream = GetDataFromProfitTrailerAsStream("/api/v2/data/stats"))
|
||||||
JObject statsDataJObject = statsDataJson as JObject;
|
using (var reader = new StreamReader(stream))
|
||||||
JObject basicSection = (JObject)statsDataJObject["basic"];
|
using (var jsonReader = new JsonTextReader(reader))
|
||||||
_stats = BuildStatsData(basicSection);
|
{
|
||||||
_statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
while (jsonReader.Read())
|
||||||
|
{
|
||||||
|
if (jsonReader.TokenType == JsonToken.PropertyName && (string)jsonReader.Value == "basic")
|
||||||
|
{
|
||||||
|
jsonReader.Read(); // Move to the value of the "basic" property
|
||||||
|
JObject basicSection = JObject.Load(jsonReader);
|
||||||
|
_stats = BuildStatsData(basicSection);
|
||||||
|
_statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _stats;
|
return _stats;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private StatsData BuildStatsData(dynamic statsDataJson)
|
private StatsData BuildStatsData(dynamic statsDataJson)
|
||||||
{
|
{
|
||||||
return new StatsData()
|
return new StatsData()
|
||||||
|
@ -194,38 +239,28 @@ namespace Core.Main.DataObjects
|
||||||
FundingTotal = statsDataJson["totalFunding"]
|
FundingTotal = statsDataJson["totalFunding"]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public List<DailyStatsData> DailyStats
|
// public List<DailyPNLData> DailyPNL
|
||||||
{
|
// {
|
||||||
get
|
// get
|
||||||
{
|
// {
|
||||||
if (_dailyStats == null || DateTime.UtcNow > _dailyStatsRefresh)
|
// if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh)
|
||||||
{
|
// {
|
||||||
lock (_dailyStatsLock)
|
// lock (_dailyPNLLock)
|
||||||
{
|
// {
|
||||||
if (_dailyStats == null || DateTime.UtcNow > _dailyStatsRefresh)
|
// if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh)
|
||||||
{
|
// {
|
||||||
dynamic dailyStatsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
|
// dynamic dailyPNLDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
|
||||||
JObject dailyStatsDataJObject = dailyStatsDataJson as JObject;
|
// JObject dailyPNLDataJObject = dailyPNLDataJson as JObject;
|
||||||
JArray dailyStatsSection = (JArray)dailyStatsDataJObject["extra"]["dailyStats"];
|
// JArray dailyPNLSection = (JArray)dailyPNLDataJObject["extra"]["dailyPNLStats"];
|
||||||
_dailyStats = dailyStatsSection.Select(j => BuildDailyStatsData(j as JObject)).ToList();
|
// _dailyPNL = dailyPNLSection.Select(j => BuildDailyPNLData(j as JObject)).ToList();
|
||||||
_dailyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
// _dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return _dailyStats;
|
// return _dailyPNL;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
private DailyStatsData BuildDailyStatsData(dynamic dailyStatsDataJson)
|
|
||||||
{
|
|
||||||
return new DailyStatsData()
|
|
||||||
{
|
|
||||||
Date = dailyStatsDataJson["date"],
|
|
||||||
TotalSales = dailyStatsDataJson["totalSales"],
|
|
||||||
TotalBuys = dailyStatsDataJson["totalBuys"],
|
|
||||||
TotalProfitCurrency = dailyStatsDataJson["totalProfitCurrency"],
|
|
||||||
Order = dailyStatsDataJson["order"],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
public List<DailyPNLData> DailyPNL
|
public List<DailyPNLData> DailyPNL
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -236,11 +271,52 @@ namespace Core.Main.DataObjects
|
||||||
{
|
{
|
||||||
if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh)
|
if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh)
|
||||||
{
|
{
|
||||||
dynamic dailyPNLDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
|
using (var stream = GetDataFromProfitTrailerAsStream("/api/v2/data/stats"))
|
||||||
JObject dailyPNLDataJObject = dailyPNLDataJson as JObject;
|
using (var reader = new StreamReader(stream))
|
||||||
JArray dailyPNLSection = (JArray)dailyPNLDataJObject["extra"]["dailyPNLStats"];
|
using (var jsonReader = new JsonTextReader(reader))
|
||||||
_dailyPNL = dailyPNLSection.Select(j => BuildDailyPNLData(j as JObject)).ToList();
|
{
|
||||||
_dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
JObject basicSection = null;
|
||||||
|
JObject extraSection = null;
|
||||||
|
|
||||||
|
while (jsonReader.Read())
|
||||||
|
{
|
||||||
|
if (jsonReader.TokenType == JsonToken.PropertyName)
|
||||||
|
{
|
||||||
|
if ((string)jsonReader.Value == "basic")
|
||||||
|
{
|
||||||
|
jsonReader.Read(); // Move to the value of the "basic" property
|
||||||
|
basicSection = JObject.Load(jsonReader);
|
||||||
|
}
|
||||||
|
else if ((string)jsonReader.Value == "extra")
|
||||||
|
{
|
||||||
|
jsonReader.Read(); // Move to the value of the "extra" property
|
||||||
|
extraSection = JObject.Load(jsonReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basicSection != null && extraSection != null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basicSection != null &&
|
||||||
|
((_totalProfit == null ||
|
||||||
|
!Decimal.Equals(_totalProfit.Value, basicSection["totalProfit"].Value<decimal>())) ||
|
||||||
|
(_totalSales == null ||
|
||||||
|
!Decimal.Equals(_totalSales.Value, basicSection["totalSales"].Value<decimal>()))))
|
||||||
|
{
|
||||||
|
_totalProfit = basicSection["totalProfit"].Value<decimal>();
|
||||||
|
_totalSales = basicSection["totalSales"].Value<decimal>();
|
||||||
|
|
||||||
|
if (extraSection != null)
|
||||||
|
{
|
||||||
|
JArray dailyPNLSection = (JArray)extraSection["dailyPNLStats"];
|
||||||
|
_dailyPNL = dailyPNLSection.Select(j => BuildDailyPNLData(j as JObject)).ToList();
|
||||||
|
_dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,6 +531,23 @@ namespace Core.Main.DataObjects
|
||||||
return JArray.Parse(rawBody);
|
return JArray.Parse(rawBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private Stream GetDataFromProfitTrailerAsStream(string callPath)
|
||||||
|
{
|
||||||
|
string url = string.Format("{0}{1}{2}token={3}", _systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL,
|
||||||
|
callPath,
|
||||||
|
callPath.Contains("?") ? "&" : "?",
|
||||||
|
_systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken);
|
||||||
|
|
||||||
|
// Get the data from PT
|
||||||
|
Debug.WriteLine(String.Format("{0} - Calling '{1}'", DateTime.UtcNow, url));
|
||||||
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||||
|
request.AutomaticDecompression = DecompressionMethods.GZip;
|
||||||
|
request.KeepAlive = true;
|
||||||
|
|
||||||
|
WebResponse response = request.GetResponse();
|
||||||
|
|
||||||
|
return response.GetResponseStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void BuildSellLogData(dynamic rawSellLogData)
|
private void BuildSellLogData(dynamic rawSellLogData)
|
||||||
|
|
|
@ -14,12 +14,11 @@ namespace Core.Main
|
||||||
{
|
{
|
||||||
public class PTMagic
|
public class PTMagic
|
||||||
{
|
{
|
||||||
|
|
||||||
public PTMagic(LogHelper log)
|
public PTMagic(LogHelper log)
|
||||||
{
|
{
|
||||||
this.Log = log;
|
this.Log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
private LogHelper _log;
|
private LogHelper _log;
|
||||||
private PTMagicConfiguration _systemConfiguration;
|
private PTMagicConfiguration _systemConfiguration;
|
||||||
|
@ -84,7 +83,10 @@ namespace Core.Main
|
||||||
_systemConfiguration = value;
|
_systemConfiguration = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public class IsAnalzyerRunning
|
||||||
|
{
|
||||||
|
private string _isAnalyzerRunning;
|
||||||
|
}
|
||||||
public System.Timers.Timer Timer
|
public System.Timers.Timer Timer
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -720,15 +722,6 @@ namespace Core.Main
|
||||||
this.Log.DoLogInfo("No CoinMarketCap API KEY specified! That's ok, but you can't use CoinMarketCap in your settings.analyzer.json");
|
this.Log.DoLogInfo("No CoinMarketCap API KEY specified! That's ok, but you can't use CoinMarketCap in your settings.analyzer.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for CurrencyConverterApi Key
|
|
||||||
//if (!this.PTMagicConfiguration.GeneralSettings.Application.FreeCurrencyConverterAPIKey.Equals(""))
|
|
||||||
//{
|
|
||||||
// this.Log.DoLogInfo("FreeCurrencyConverterApi KEY found");
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// this.Log.DoLogInfo("No FreeCurrencyConverterApi KEY specified. That's ok! But you can only use USD; apply for a key at: https://freecurrencyrates.com/en");
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
catch (System.NullReferenceException)
|
catch (System.NullReferenceException)
|
||||||
{
|
{
|
||||||
|
@ -871,9 +864,6 @@ namespace Core.Main
|
||||||
// Check for latest GitHub version
|
// Check for latest GitHub version
|
||||||
this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version);
|
this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version);
|
||||||
|
|
||||||
// Get latest main fiat currency exchange rate
|
|
||||||
// this.GetMainFiatCurrencyDetails();
|
|
||||||
|
|
||||||
// Load current PT files
|
// Load current PT files
|
||||||
this.LoadCurrentProfitTrailerProperties();
|
this.LoadCurrentProfitTrailerProperties();
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Monitor.Pages
|
||||||
{
|
{
|
||||||
HttpContext.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
|
HttpContext.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
|
||||||
PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected = true;
|
PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected = true;
|
||||||
PTMagicConfiguration.WriteGeneralSettings();
|
//PTMagicConfiguration.WriteGeneralSettings();
|
||||||
if (cbRememberMe != null)
|
if (cbRememberMe != null)
|
||||||
{
|
{
|
||||||
if (cbRememberMe.Equals("on", StringComparison.InvariantCultureIgnoreCase))
|
if (cbRememberMe.Equals("on", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="card-box">
|
<div class="card-box">
|
||||||
<h4 class="m-t-0 header-title text-center">Cumulative Profits <small> <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This value is based on your sales history"></i></small></h4>
|
<h4 class="m-t-0 header-title text-center">Cumulative PNL <small> <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This value is based on your sales history"></i></small></h4>
|
||||||
<div class="balance-chart">
|
<div class="balance-chart">
|
||||||
<svg style="height:350px;width:100%"></svg>
|
<svg style="height:350px;width:100%"></svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -203,12 +203,19 @@
|
||||||
</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."></i></label>
|
<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 in hours."></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">
|
||||||
|
<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."></i></label>
|
||||||
|
<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"))">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-md-4 col-form-label">Refresh Seconds <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval of your monitor main page."></i></label>
|
<label class="col-md-4 col-form-label">Refresh Seconds <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The refresh interval of your monitor main page."></i></label>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
|
|
|
@ -90,6 +90,7 @@ namespace Monitor.Pages
|
||||||
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.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.RefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_RefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds);
|
PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds = SystemHelper.TextToInteger(HttpContext.Request.Form["Monitor_RefreshSeconds"], PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds);
|
||||||
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);
|
||||||
|
|
|
@ -81,34 +81,38 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var marketTrend in Model.MarketTrends.OrderBy(mt => mt.TrendMinutes)) {
|
@foreach (var marketTrend in Model.MarketTrends.OrderBy(mt => mt.TrendMinutes)) {
|
||||||
if (Model.Summary.MarketTrendChanges.ContainsKey(marketTrend.Name)) {
|
if (Model.Summary.MarketTrendChanges.ContainsKey(marketTrend.Name)) {
|
||||||
double trendChange = Model.Summary.MarketTrendChanges[marketTrend.Name].OrderByDescending(mtc => mtc.TrendDateTime).First().TrendChange;
|
double trendChange = Model.Summary.MarketTrendChanges[marketTrend.Name].Last().TrendChange;
|
||||||
string trendChangeOutput = trendChange.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
|
string trendChangeOutput = trendChange.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
|
||||||
|
|
||||||
int marketCount = marketTrend.MaxMarkets;
|
int marketCount = marketTrend.MaxMarkets;
|
||||||
string marketCountString = marketCount.ToString();
|
string marketCountString = marketCount.ToString();
|
||||||
|
|
||||||
if (marketCount == 0) {
|
if (marketCount == 0) {
|
||||||
marketCountString = "All";
|
marketCountString = "All";
|
||||||
} else if (marketCount > Model.Summary.MarketSummary.Keys.Count && marketTrend.Platform.Equals("Exchange", StringComparison.InvariantCultureIgnoreCase)) {
|
} else if (marketCount > Model.Summary.MarketSummary.Keys.Count && marketTrend.Platform.Equals("Exchange", StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
marketCountString = Model.Summary.MarketSummary.Keys.Count.ToString();
|
marketCountString = Model.Summary.MarketSummary.Keys.Count.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the result of SplitCamelCase(marketTrend.Name)
|
||||||
|
string splitCamelCaseName = Core.Helper.SystemHelper.SplitCamelCase(marketTrend.Name);
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>@splitCamelCaseName</td> <!-- Use the cached value here -->
|
||||||
|
<td class="text-right">@marketCountString</td>
|
||||||
|
<td class="text-right">@Core.Helper.SystemHelper.GetProperDurationTime(marketTrend.TrendMinutes * 60, false)</td>
|
||||||
|
@if (marketTrend.TrendThreshold == 0)
|
||||||
|
{
|
||||||
|
<td class="text-right">--</td>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<td class="text-right">@marketTrend.TrendThreshold</td>
|
||||||
|
}
|
||||||
|
<td class="text-right text-autocolor">@trendChangeOutput%</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
<tr>
|
|
||||||
<td>@Core.Helper.SystemHelper.SplitCamelCase(marketTrend.Name)</td>
|
|
||||||
<td class="text-right">@marketCountString</td>
|
|
||||||
<td class="text-right">@Core.Helper.SystemHelper.GetProperDurationTime(marketTrend.TrendMinutes * 60, false)</td>
|
|
||||||
@if (marketTrend.TrendThreshold == 0)
|
|
||||||
{
|
|
||||||
<td class="text-right">--</td>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<td class="text-right">@marketTrend.TrendThreshold</td>
|
|
||||||
}
|
|
||||||
<td class="text-right text-autocolor">@trendChangeOutput%</td>
|
|
||||||
</tr>
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,8 +17,7 @@ namespace Monitor.Pages
|
||||||
public StatsData StatsData { get; set; }
|
public StatsData StatsData { get; set; }
|
||||||
public PropertiesData PropertiesData { get; set; }
|
public PropertiesData PropertiesData { get; set; }
|
||||||
public SummaryData SummaryData { get; set; }
|
public SummaryData SummaryData { get; set; }
|
||||||
public List<DailyStatsData> DailyStats { get; set; } = new List<DailyStatsData>();
|
|
||||||
public List<DailyPNLData> DailyPNL { get; set; } = new List<DailyPNLData>();
|
|
||||||
public List<MarketTrend> MarketTrends { get; set; } = new List<MarketTrend>();
|
public List<MarketTrend> MarketTrends { get; set; } = new List<MarketTrend>();
|
||||||
public string TrendChartDataJSON = "";
|
public string TrendChartDataJSON = "";
|
||||||
public string ProfitChartDataJSON = "";
|
public string ProfitChartDataJSON = "";
|
||||||
|
@ -42,7 +41,7 @@ namespace Monitor.Pages
|
||||||
StatsData = this.PTData.Stats;
|
StatsData = this.PTData.Stats;
|
||||||
PropertiesData = this.PTData.Properties;
|
PropertiesData = this.PTData.Properties;
|
||||||
SummaryData = this.PTData.Summary;
|
SummaryData = this.PTData.Summary;
|
||||||
List<DailyStatsData> dailyStatsData = this.PTData.DailyStats;
|
|
||||||
List<DailyPNLData> dailyPNLData = this.PTData.DailyPNL;
|
List<DailyPNLData> dailyPNLData = this.PTData.DailyPNL;
|
||||||
|
|
||||||
// Cleanup temp files
|
// Cleanup temp files
|
||||||
|
@ -66,96 +65,103 @@ namespace Monitor.Pages
|
||||||
BuildProfitChartData();
|
BuildProfitChartData();
|
||||||
}
|
}
|
||||||
private void BuildMarketTrendChartData()
|
private void BuildMarketTrendChartData()
|
||||||
{
|
|
||||||
StringBuilder trendChartDataJSON = new StringBuilder();
|
|
||||||
if (MarketTrends.Count > 0)
|
|
||||||
{
|
{
|
||||||
trendChartDataJSON.Append("[");
|
List<string> trendChartData = new List<string>();
|
||||||
int mtIndex = 0;
|
if (MarketTrends.Count > 0)
|
||||||
foreach (MarketTrend mt in MarketTrends)
|
|
||||||
{
|
{
|
||||||
if (mt.DisplayGraph)
|
|
||||||
|
int mtIndex = 0;
|
||||||
|
foreach (MarketTrend mt in MarketTrends)
|
||||||
{
|
{
|
||||||
string lineColor = "";
|
if (mt.DisplayGraph)
|
||||||
if (mtIndex < Constants.ChartLineColors.Length)
|
|
||||||
{
|
{
|
||||||
lineColor = Constants.ChartLineColors[mtIndex];
|
string lineColor = mtIndex < Constants.ChartLineColors.Length
|
||||||
}
|
? Constants.ChartLineColors[mtIndex]
|
||||||
else
|
: Constants.ChartLineColors[mtIndex - 20];
|
||||||
{
|
|
||||||
lineColor = Constants.ChartLineColors[mtIndex - 20];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Summary.MarketTrendChanges.ContainsKey(mt.Name))
|
if (Summary.MarketTrendChanges.ContainsKey(mt.Name))
|
||||||
{
|
|
||||||
List<MarketTrendChange> marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name];
|
|
||||||
|
|
||||||
if (marketTrendChangeSummaries.Count > 0)
|
|
||||||
{
|
{
|
||||||
if (!trendChartDataJSON.ToString().Equals("[")) trendChartDataJSON.Append(",");
|
List<MarketTrendChange> marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name];
|
||||||
|
|
||||||
trendChartDataJSON.Append("{");
|
if (marketTrendChangeSummaries.Count > 0)
|
||||||
trendChartDataJSON.Append("key: '" + SystemHelper.SplitCamelCase(mt.Name) + "',");
|
|
||||||
trendChartDataJSON.Append("color: '" + lineColor + "',");
|
|
||||||
trendChartDataJSON.Append("values: [");
|
|
||||||
|
|
||||||
// Get trend ticks for chart
|
|
||||||
DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0);
|
|
||||||
DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours);
|
|
||||||
DateTime endDateTime = currentDateTime;
|
|
||||||
int trendChartTicks = 0;
|
|
||||||
for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes))
|
|
||||||
{
|
{
|
||||||
List<MarketTrendChange> tickRange = marketTrendChangeSummaries.FindAll(m => m.TrendDateTime >= tickTime).OrderBy(m => m.TrendDateTime).ToList();
|
List<string> trendValues = new List<string>();
|
||||||
if (tickRange.Count > 0)
|
|
||||||
|
// Sort marketTrendChangeSummaries by TrendDateTime
|
||||||
|
marketTrendChangeSummaries = marketTrendChangeSummaries.OrderBy(m => m.TrendDateTime).ToList();
|
||||||
|
|
||||||
|
// Get trend ticks for chart
|
||||||
|
DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0);
|
||||||
|
DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours);
|
||||||
|
DateTime endDateTime = currentDateTime;
|
||||||
|
|
||||||
|
// Cache the result of SplitCamelCase(mt.Name)
|
||||||
|
string splitCamelCaseName = SystemHelper.SplitCamelCase(mt.Name);
|
||||||
|
|
||||||
|
for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes))
|
||||||
{
|
{
|
||||||
MarketTrendChange mtc = tickRange.First();
|
// Use binary search to find the range of items that match the condition
|
||||||
if (tickTime != startDateTime) trendChartDataJSON.Append(",\n");
|
int index = marketTrendChangeSummaries.BinarySearch(new MarketTrendChange { TrendDateTime = tickTime }, Comparer<MarketTrendChange>.Create((x, y) => x.TrendDateTime.CompareTo(y.TrendDateTime)));
|
||||||
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
|
if (index < 0) index = ~index;
|
||||||
|
if (index < marketTrendChangeSummaries.Count)
|
||||||
|
{
|
||||||
|
MarketTrendChange mtc = marketTrendChangeSummaries[index];
|
||||||
|
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
|
||||||
|
|
||||||
trendChartDataJSON.Append("{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}");
|
trendValues.Add("{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", CultureInfo.InvariantCulture) + "}");
|
||||||
trendChartTicks++;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add most recent tick
|
||||||
|
MarketTrendChange latestMtc = marketTrendChangeSummaries.Last();
|
||||||
|
if (Double.IsInfinity(latestMtc.TrendChange)) latestMtc.TrendChange = 0;
|
||||||
|
trendValues.Add("{ x: new Date('" + latestMtc.TrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + latestMtc.TrendChange.ToString("0.00", CultureInfo.InvariantCulture) + "}");
|
||||||
|
|
||||||
|
// Use cached splitCamelCaseName
|
||||||
|
trendChartData.Add("{ key: '" + splitCamelCaseName + "', color: '" + lineColor + "', values: [" + string.Join(",\n", trendValues) + "] }");
|
||||||
|
mtIndex++;
|
||||||
}
|
}
|
||||||
// Add most recent tick
|
|
||||||
List<MarketTrendChange> latestTickRange = marketTrendChangeSummaries.OrderByDescending(m => m.TrendDateTime).ToList();
|
|
||||||
if (latestTickRange.Count > 0)
|
|
||||||
{
|
|
||||||
MarketTrendChange mtc = latestTickRange.First();
|
|
||||||
if (trendChartTicks > 0) trendChartDataJSON.Append(",\n");
|
|
||||||
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
|
|
||||||
trendChartDataJSON.Append("{ x: new Date('" + mtc.TrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}");
|
|
||||||
}
|
|
||||||
trendChartDataJSON.Append("]");
|
|
||||||
trendChartDataJSON.Append("}");
|
|
||||||
mtIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
trendChartDataJSON.Append("]");
|
TrendChartDataJSON = "[" + string.Join(",", trendChartData) + "]";
|
||||||
}
|
}
|
||||||
TrendChartDataJSON = trendChartDataJSON.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BuildProfitChartData()
|
private void BuildProfitChartData()
|
||||||
{
|
{
|
||||||
StringBuilder profitPerDayJSON = new StringBuilder();
|
StringBuilder profitPerDayJSON = new StringBuilder();
|
||||||
|
|
||||||
if (PTData.DailyStats.Count > 0)
|
if (PTData.DailyPNL.Count > 0)
|
||||||
{
|
{
|
||||||
DateTime endDate = DateTime.UtcNow.Date;
|
DateTime endDate = DateTime.UtcNow.Date;
|
||||||
DateTime startDate = endDate.AddDays(-30);
|
DateTime startDate = endDate.AddDays(-PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays - 1); // Fetch data for timeframe + 1 days
|
||||||
|
double previousDayCumulativeProfit = 0;
|
||||||
|
bool isFirstDay = true;
|
||||||
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
|
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
|
||||||
{
|
{
|
||||||
if (profitPerDayJSON.Length > 0)
|
DailyPNLData dailyPNL = PTData.DailyPNL.Find(ds => DateTime.ParseExact(ds.Date, "d-M-yyyy", CultureInfo.InvariantCulture) == date);
|
||||||
|
if (dailyPNL != null)
|
||||||
{
|
{
|
||||||
profitPerDayJSON.Append(",\n");
|
if (isFirstDay)
|
||||||
|
{
|
||||||
|
isFirstDay = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Calculate the profit for the current day
|
||||||
|
double profitFiat = Math.Round(dailyPNL.CumulativeProfitCurrency - previousDayCumulativeProfit, 2);
|
||||||
|
|
||||||
|
// Add the data point to the JSON string
|
||||||
|
if (profitPerDayJSON.Length > 0)
|
||||||
|
{
|
||||||
|
profitPerDayJSON.Append(",\n");
|
||||||
|
}
|
||||||
|
profitPerDayJSON.Append("{x: new Date('" + date.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}");
|
||||||
|
}
|
||||||
|
previousDayCumulativeProfit = dailyPNL.CumulativeProfitCurrency;
|
||||||
}
|
}
|
||||||
DailyStatsData dailyStats = PTData.DailyStats.Find(ds => DateTime.ParseExact(ds.Date, "d-M-yyyy", CultureInfo.InvariantCulture) == date);
|
|
||||||
double profitFiat = dailyStats != null ? Math.Round(dailyStats.TotalProfitCurrency,2) : 0;
|
|
||||||
profitPerDayJSON.Append("{x: new Date('" + date.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}");
|
|
||||||
}
|
}
|
||||||
ProfitChartDataJSON = "[{key: 'Profit in " + PTData.Properties.Currency + "',color: '" + Constants.ChartLineColors[1] + "',values: [" + profitPerDayJSON.ToString() + "]}]";
|
ProfitChartDataJSON = "[{key: 'Profit in " + PTData.Properties.Currency + "',color: '" + Constants.ChartLineColors[1] + "',values: [" + profitPerDayJSON.ToString() + "]}]";
|
||||||
}
|
}
|
||||||
|
@ -171,8 +177,8 @@ namespace Monitor.Pages
|
||||||
bool isSellStrategyTrue = false;
|
bool isSellStrategyTrue = false;
|
||||||
bool isTrailingSellActive = false;
|
bool isTrailingSellActive = false;
|
||||||
|
|
||||||
foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog)
|
foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog)
|
||||||
{
|
{
|
||||||
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
|
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
|
||||||
|
|
||||||
// Aggregate totals
|
// Aggregate totals
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
"Port": 8080, // The port you want to run your monitor on
|
"Port": 8080, // The port you want to run your monitor on
|
||||||
"RootUrl": "/", // The root Url of your monitor
|
"RootUrl": "/", // The root Url of your monitor
|
||||||
"AnalyzerChart": "", // By default the chart on the Market Analyzer page will use your default currency against USD. You can change that here. (eg., BTCEUR)
|
"AnalyzerChart": "", // By default the chart on the Market Analyzer page will use your default currency against USD. You can change that here. (eg., BTCEUR)
|
||||||
"GraphIntervalMinutes": 60, // The interval for the monitor market trend graph to draw points
|
"GraphIntervalMinutes": 60, // The interval for the monitor market trend graph to draw points in minutes
|
||||||
"GraphMaxTimeframeHours": 24, // This will enable you to define the timeframe that your graph for market trends covers
|
"GraphMaxTimeframeHours": 24, // This will enable you to define the timeframe that your graph for market trends covers in hours
|
||||||
|
"ProfitsMaxTimeframeDays": 30, // This will enable you to define the timeframe for your dashboard profits graph in days
|
||||||
"RefreshSeconds": 30, // The refresh interval of your monitor main page
|
"RefreshSeconds": 30, // The refresh interval of your monitor main page
|
||||||
"LinkPlatform": "TradingView", // The platform to which the pair name will link if you click on it
|
"LinkPlatform": "TradingView", // The platform to which the pair name will link if you click on it
|
||||||
"MaxSalesRecords": 99999, // The maximum number of sales records pulled from Profit Trailer. Changes require a Monitor Restart.
|
"MaxSalesRecords": 99999, // The maximum number of sales records pulled from Profit Trailer. Changes require a Monitor Restart.
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
"Port": 8080, // The port you want to run your monitor on
|
"Port": 8080, // The port you want to run your monitor on
|
||||||
"RootUrl": "/", // The root Url of your monitor
|
"RootUrl": "/", // The root Url of your monitor
|
||||||
"AnalyzerChart": "", // By default the chart on the Market Analyzer page will use your default currency against USD. You can change that here. (eg., BTCEUR)
|
"AnalyzerChart": "", // By default the chart on the Market Analyzer page will use your default currency against USD. You can change that here. (eg., BTCEUR)
|
||||||
"GraphIntervalMinutes": 60, // The interval for the monitor market trend graph to draw points
|
"GraphIntervalMinutes": 60, // The interval for the monitor market trend graph to draw points in minutes
|
||||||
"GraphMaxTimeframeHours": 24, // This will enable you to define the timeframe that your graph for market trends covers
|
"GraphMaxTimeframeHours": 24, // This will enable you to define the timeframe that your graph for market trends covers in hours
|
||||||
|
"ProfitsMaxTimeframeDays": 30, // This will enable you to define the timeframe for your dashboard profits graph in days
|
||||||
"RefreshSeconds": 30, // The refresh interval of your monitor main page
|
"RefreshSeconds": 30, // The refresh interval of your monitor main page
|
||||||
"LinkPlatform": "TradingView", // The platform to which the pair name will link if you click on it
|
"LinkPlatform": "TradingView", // The platform to which the pair name will link if you click on it
|
||||||
"MaxSalesRecords": 99999, // The maximum number of sales records pulled from Profit Trailer. Changes require a Monitor Restart.
|
"MaxSalesRecords": 99999, // The maximum number of sales records pulled from Profit Trailer. Changes require a Monitor Restart.
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
- This version of PT Magic only works with Profit Trailer v2.4.x and above
|
- This version of PT Magic only works with Profit Trailer v2.4.x and above
|
||||||
|
|
||||||
### .Net
|
### .Net
|
||||||
- PTMagic requires .Net Core Runtime 3.1 on the host operating system (download: https://dotnet.microsoft.com/download)
|
- PTMagic requires .Net Core Runtime 7 on the host operating system (download: https://dotnet.microsoft.com/download)
|
||||||
|
|
||||||
### Settings
|
### Settings
|
||||||
- **If you are updating from any version of PTMagic prior to 2.4.1,** check the default settings included with this release for any new lines that might need to be added to your settings.general.json file.
|
- **If you are updating from any version of PTMagic prior to 2.4.1,** check the default settings included with this release for any new lines that might need to be added to your settings.general.json file.
|
||||||
|
|
Loading…
Reference in New Issue