Dashboard Bottom

This commit is contained in:
HojouFotytu 2024-01-08 06:53:49 +09:00
parent bde9b98f11
commit 28c12e6d5a
12 changed files with 521 additions and 372 deletions

View File

@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace Core.Main.DataObjects.PTMagicData
{
#region Settings Objects
public class GeneralSettingsWrapper
{
public GeneralSettings GeneralSettings { get; set; }
@ -21,7 +19,7 @@ namespace Core.Main.DataObjects.PTMagicData
public SecureSettings SecureSettings { get; set; }
}
#region GeneralSettings
public class GeneralSettings
{
public Application Application { get; set; }
@ -43,7 +41,7 @@ namespace Core.Main.DataObjects.PTMagicData
public string ProfitTrailerDefaultSettingName { get; set; } = "default";
public int FloodProtectionMinutes { get; set; } = 15;
public string Exchange { get; set; }
public double StartBalance { get; set; } = 0;
//public double StartBalance { get; set; } = 0;
public string InstanceName { get; set; } = "PT Magic";
public string TimezoneOffset { get; set; } = "+0:00";
public string MainFiatCurrency { get; set; } = "USD";
@ -106,9 +104,7 @@ namespace Core.Main.DataObjects.PTMagicData
public Int64 ChatId { get; set; }
public bool SilentMode { get; set; } = false;
}
#endregion
#region AnalyzerSettings
public class AnalyzerSettings
{
public MarketAnalyzer MarketAnalyzer { get; set; }
@ -244,18 +240,12 @@ namespace Core.Main.DataObjects.PTMagicData
[DefaultValue(0)]
public int HoursSinceTriggered { get; set; } = 0;
}
#endregion
#region SecureSettings
public class SecureSettings
{
public string MonitorPassword { get; set; } = "";
}
#endregion
#endregion
#region Market Analyzer Objects
public class Market
{
public int Position;
@ -291,9 +281,7 @@ namespace Core.Main.DataObjects.PTMagicData
public DateTime FirstSeen = Constants.confMinDate;
public DateTime LastSeen = Constants.confMaxDate;
}
#endregion
#region Summary Objects
public class Summary
{
public string Version { get; set; } = "";
@ -324,13 +312,25 @@ namespace Core.Main.DataObjects.PTMagicData
public string SellStrategy { get; set; } = "";
public string MainMarket { get; set; } = "";
public double MainMarketPrice { get; set; } = 0;
public string MainFiatCurrency { get; set; } = "USD";
public double MainFiatCurrencyExchangeRate { get; set; } = 1;
private PropertiesData _propertiesData = new PropertiesData();
public string MainFiatCurrency => _propertiesData.Currency;
private SummaryData _summaryData = new SummaryData();
public double MainFiatCurrencyExchangeRate => _summaryData.FiatConversionRate;
public List<StrategySummary> BuyStrategies { get; set; } = new List<StrategySummary>();
public List<StrategySummary> SellStrategies { get; set; } = new List<StrategySummary>();
public List<StrategySummary> DCABuyStrategies { get; set; } = new List<StrategySummary>();
public List<StrategySummary> DCASellStrategies { get; set; } = new List<StrategySummary>();
}
public class PropertiesData
{
public string Currency { get; set; } = "";
public bool Shorting { get; set; } = false;
public bool Margin { get; set; } = false;
public string UpTime { get; set; } = "";
public int Port { get; set; } = 0;
public bool IsLeverageExchange { get; set; } = false;
public string BaseUrl { get; set; } = "";
}
public class StrategySummary
{
@ -364,22 +364,7 @@ namespace Core.Main.DataObjects.PTMagicData
public List<StrategySummary> DCABuyStrategies { get; set; } = new List<StrategySummary>();
public List<StrategySummary> DCASellStrategies { get; set; } = new List<StrategySummary>();
}
#endregion
#region Properties Objects
public class Properties
{
public string Currency { get; set; } = "";
public bool Shorting { get; set; } = false;
public bool Margin { get; set; } = false;
public string UpTime { get; set; } = "";
public int Port { get; set; } = 0;
public bool IsLeverageExchange { get; set; } = false;
public string BaseUrl { get; set; } = "";
}
#endregion
#region Transaction Objects
public class Transaction
{
public string GUID { get; set; } = "";
@ -397,9 +382,7 @@ namespace Core.Main.DataObjects.PTMagicData
return result.DateTime;
}
}
#endregion
#region SingleMarketSettingSummary Objects
public class SingleMarketSettingSummary
{
public string Market { get; set; } = "";
@ -415,11 +398,8 @@ namespace Core.Main.DataObjects.PTMagicData
public double LastPrice { get; set; } = 0;
public double Last24hVolume { get; set; } = 0;
}
#endregion
#region Profit Trailer JSON Objects
public class SellLogData
public class SellLogData
{
public double SoldAmount { get; set; }
public DateTime SoldDate { get; set; }
@ -445,19 +425,39 @@ namespace Core.Main.DataObjects.PTMagicData
public double SalesWeek { get; set; }
public double ProfitWeek { get; set; }
public double ProfitPercWeek { get; set; }
public double SalesMonth { get; set; }
public double ProfitMonth { get; set; }
public double ProfitPercMonth { get; set; }
public double SalesThisMonth { get; set; }
public double ProfitThisMonth { get; set; }
public double ProfitPercThisMonth { get; set; }
public double SalesLastMonth { get; set; }
public double ProfitLastMonth { get; set; }
public double ProfitPercLastMonth { get; set; }
public double TotalProfit { get; set; }
public double TotalSales { get; set; }
public double TotalProfitPerc { get; set; }
public double FundingToday { get; set; }
public double FundingYesterday { get; set; }
public double FundingWeek { get; set; }
public double FundingMonth { get; set; }
public double FundingThisMonth { get; set; }
public double FundingLastMonth { get; set; }
public double FundingTotal { get; set; }
}
public class DailyStatsData
{
public string Date { get; set; }
public double TotalSales { get; set; }
public double TotalBuys { get; set; }
public double TotalProfitCurrency { get; set; }
public int Order { get; set; }
}
public class DailyPNLData
{
public string Date { get; set; }
public double CumulativeProfitCurrency { get; set; }
public double Order { get; set; }
}
public class PTStrategy
{
public string type { get; set; }
@ -534,15 +534,13 @@ namespace Core.Main.DataObjects.PTMagicData
}
public class SummaryData
{
public double Balance { get; set; }
{ public double Balance { get; set; }
public double StartBalance { get; set; }
public double FiatConversionRate { get; set; }
public double PairsValue { get; set; }
public double DCAValue { get; set; }
public double PendingValue { get; set; }
public double DustValue { get; set; }
public string Market { get; set; }
}
#endregion
}

View File

@ -15,18 +15,32 @@ namespace Core.Main.DataObjects
public class ProfitTrailerData
{
private SummaryData _summary = null;
private Properties _properties = null;
private List<StatsData> _stats = null;
private PropertiesData _properties = null;
private StatsData _stats = null;
private List<DailyStatsData> _dailyStats = new List<DailyStatsData>();
private List<DailyPNLData> _dailyPNL = new List<DailyPNLData>();
private List<SellLogData> _sellLog = new List<SellLogData>();
private List<DCALogData> _dcaLog = new List<DCALogData>();
private List<BuyLogData> _buyLog = new List<BuyLogData>();
private string _ptmBasePath = "";
private PTMagicConfiguration _systemConfiguration = null;
private TransactionData _transactionData = null;
private DateTime _statsRefresh = DateTime.UtcNow,_buyLogRefresh = DateTime.UtcNow, _sellLogRefresh = DateTime.UtcNow, _dcaLogRefresh = DateTime.UtcNow, _summaryRefresh = DateTime.UtcNow, _propertiesRefresh = DateTime.UtcNow;
private volatile object _statsLock = new object(),_buyLock = new object(), _sellLock = new object(), _dcaLock = new object(), _summaryLock = new object(), _propertiesLock = new object();
private TimeSpan? _offsetTimeSpan = null;
private DateTime _dailyStatsRefresh = DateTime.UtcNow;
private DateTime _dailyPNLRefresh = DateTime.UtcNow;
private DateTime _statsRefresh = DateTime.UtcNow;
private DateTime _buyLogRefresh = DateTime.UtcNow;
private DateTime _sellLogRefresh = DateTime.UtcNow;
private DateTime _dcaLogRefresh = DateTime.UtcNow;
private DateTime _summaryRefresh = DateTime.UtcNow;
private DateTime _propertiesRefresh = DateTime.UtcNow;
private volatile object _dailyStatsLock = new object();
private volatile object _dailyPNLLock = new object();
private volatile object _statsLock = new object();
private volatile object _buyLock = new object();
private volatile object _sellLock = new object();
private volatile object _dcaLock = new object();
private volatile object _summaryLock = new object();
private volatile object _propertiesLock = new object(); private TimeSpan? _offsetTimeSpan = null;
public void DoLog(string message)
{
// Implement your logging logic here
@ -82,7 +96,21 @@ namespace Core.Main.DataObjects
return _summary;
}
}
public Properties Properties
private SummaryData BuildSummaryData(dynamic PTData)
{
return new SummaryData()
{
Market = PTData.market,
FiatConversionRate = PTData.priceDataFiatConversionRate,
Balance = PTData.realBalance,
PairsValue = PTData.totalPairsCurrentValue,
DCAValue = PTData.totalDCACurrentValue,
PendingValue = PTData.totalPendingCurrentValue,
DustValue = PTData.totalDustCurrentValue,
StartBalance = PTData.startBalance,
};
}
public PropertiesData Properties
{
get
{
@ -102,8 +130,20 @@ namespace Core.Main.DataObjects
return _properties;
}
}
public List<StatsData> Stats
private PropertiesData BuildProptertiesData(dynamic PTProperties)
{
return new PropertiesData()
{
Currency = PTProperties.currency,
Shorting = PTProperties.shorting,
Margin = PTProperties.margin,
UpTime = PTProperties.upTime,
Port = PTProperties.port,
IsLeverageExchange = PTProperties.isLeverageExchange,
BaseUrl = PTProperties.baseUrl
};
}
public StatsData Stats
{
get
{
@ -116,7 +156,7 @@ namespace Core.Main.DataObjects
dynamic statsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
JObject statsDataJObject = statsDataJson as JObject;
JObject basicSection = (JObject)statsDataJObject["basic"];
_stats = new List<StatsData> { BuildStatsData(basicSection) };
_stats = BuildStatsData(basicSection);
_statsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
@ -124,8 +164,98 @@ namespace Core.Main.DataObjects
return _stats;
}
}
private StatsData BuildStatsData(dynamic statsDataJson)
{
return new StatsData()
{
SalesToday = statsDataJson["totalSalesToday"],
ProfitToday = statsDataJson["totalProfitToday"],
ProfitPercToday = statsDataJson["totalProfitPercToday"],
SalesYesterday = statsDataJson["totalSalesYesterday"],
ProfitYesterday = statsDataJson["totalProfitYesterday"],
ProfitPercYesterday = statsDataJson["totalProfitPercYesterday"],
SalesWeek = statsDataJson["totalSalesWeek"],
ProfitWeek = statsDataJson["totalProfitWeek"],
ProfitPercWeek = statsDataJson["totalProfitPercWeek"],
SalesThisMonth = statsDataJson["totalSalesThisMonth"],
ProfitThisMonth = statsDataJson["totalProfitThisMonth"],
ProfitPercThisMonth = statsDataJson["totalProfitPercThisMonth"],
SalesLastMonth = statsDataJson["totalSalesLastMonth"],
ProfitLastMonth = statsDataJson["totalProfitLastMonth"],
ProfitPercLastMonth = statsDataJson["totalProfitPercLastMonth"],
TotalProfit = statsDataJson["totalProfit"],
TotalSales = statsDataJson["totalSales"],
TotalProfitPerc = statsDataJson["totalProfitPerc"],
FundingToday = statsDataJson["totalFundingToday"],
FundingYesterday = statsDataJson["totalFundingYesterday"],
FundingWeek = statsDataJson["totalFundingWeek"],
FundingThisMonth = statsDataJson["totalFundingThisMonth"],
FundingLastMonth = statsDataJson["totalFundingLastMonth"],
FundingTotal = statsDataJson["totalFunding"]
};
}
public List<DailyStatsData> DailyStats
{
get
{
if (_dailyStats == null || DateTime.UtcNow > _dailyStatsRefresh)
{
lock (_dailyStatsLock)
{
if (_dailyStats == null || DateTime.UtcNow > _dailyStatsRefresh)
{
dynamic dailyStatsDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
JObject dailyStatsDataJObject = dailyStatsDataJson as JObject;
JArray dailyStatsSection = (JArray)dailyStatsDataJObject["extra"]["dailyStats"];
_dailyStats = dailyStatsSection.Select(j => BuildDailyStatsData(j as JObject)).ToList();
_dailyStatsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
}
return _dailyStats;
}
}
private DailyStatsData BuildDailyStatsData(dynamic dailyStatsDataJson)
{
return new DailyStatsData()
{
Date = dailyStatsDataJson["date"],
TotalSales = dailyStatsDataJson["totalSales"],
TotalBuys = dailyStatsDataJson["totalBuys"],
TotalProfitCurrency = dailyStatsDataJson["totalProfitCurrency"],
Order = dailyStatsDataJson["order"],
};
}
public List<DailyPNLData> DailyPNL
{
get
{
if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh)
{
lock (_dailyPNLLock)
{
if (_dailyPNL == null || DateTime.UtcNow > _dailyPNLRefresh)
{
dynamic dailyPNLDataJson = GetDataFromProfitTrailer("/api/v2/data/stats");
JObject dailyPNLDataJObject = dailyPNLDataJson as JObject;
JArray dailyPNLSection = (JArray)dailyPNLDataJObject["extra"]["dailyPNLStats"];
_dailyPNL = dailyPNLSection.Select(j => BuildDailyPNLData(j as JObject)).ToList();
_dailyPNLRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
}
return _dailyPNL;
}
}
private DailyPNLData BuildDailyPNLData(dynamic dailyPNLDataJson)
{
return new DailyPNLData()
{
Date = dailyPNLDataJson["date"],
CumulativeProfitCurrency = dailyPNLDataJson["cumulativeProfitCurrency"],
Order = dailyPNLDataJson["order"],
};
}
public List<SellLogData> SellLog
{
get
@ -203,7 +333,6 @@ namespace Core.Main.DataObjects
() =>
{
pendingData = GetDataFromProfitTrailer("/api/v2/data/pending", true);
},
() =>
{
@ -277,9 +406,10 @@ namespace Core.Main.DataObjects
(this.Summary.DustValue);
}
public double GetSnapshotBalance(DateTime snapshotDateTime)
{
double result = _systemConfiguration.GeneralSettings.Application.StartBalance;
double result = _summary.StartBalance;
result += this.SellLog.FindAll(sl => sl.SoldDate.Date < snapshotDateTime.Date).Sum(sl => sl.Profit);
result += this.TransactionData.Transactions.FindAll(t => t.UTCDateTime < snapshotDateTime).Sum(t => t.Amount);
@ -324,62 +454,9 @@ namespace Core.Main.DataObjects
{
return JArray.Parse(rawBody);
}
}
private SummaryData BuildSummaryData(dynamic PTData)
{
return new SummaryData()
{
Market = PTData.market,
Balance = PTData.realBalance,
PairsValue = PTData.totalPairsCurrentValue,
DCAValue = PTData.totalDCACurrentValue,
PendingValue = PTData.totalPendingCurrentValue,
DustValue = PTData.totalDustCurrentValue
};
}
private Properties BuildProptertiesData(dynamic PTProperties)
{
return new Properties()
{
Currency = PTProperties.currency,
Shorting = PTProperties.shorting,
Margin = PTProperties.margin,
UpTime = PTProperties.upTime,
Port = PTProperties.port,
IsLeverageExchange = PTProperties.isLeverageExchange,
BaseUrl = PTProperties.baseUrl
};
}
private StatsData BuildStatsData(dynamic statsDataJson)
{
return new StatsData()
{
SalesToday = statsDataJson["totalSalesToday"],
ProfitToday = statsDataJson["totalProfitToday"],
ProfitPercToday = statsDataJson["totalProfitPercToday"],
SalesYesterday = statsDataJson["totalSalesYesterday"],
ProfitYesterday = statsDataJson["totalProfitYesterday"],
ProfitPercYesterday = statsDataJson["totalProfitPercYesterday"],
SalesWeek = statsDataJson["totalSalesWeek"],
ProfitWeek = statsDataJson["totalProfitWeek"],
ProfitPercWeek = statsDataJson["totalProfitPercWeek"],
SalesMonth = statsDataJson["totalSalesThisMonth"],
ProfitMonth = statsDataJson["totalProfitThisMonth"],
ProfitPercMonth = statsDataJson["totalProfitPercThisMonth"],
TotalProfit = statsDataJson["totalProfit"],
TotalSales = statsDataJson["totalSales"],
TotalProfitPerc = statsDataJson["totalProfitPerc"],
FundingToday = statsDataJson["totalFundingToday"],
FundingYesterday = statsDataJson["totalFundingYesterday"],
FundingWeek = statsDataJson["totalFundingWeek"],
FundingMonth = statsDataJson["totalFundingThisMonth"],
FundingTotal = statsDataJson["totalFunding"]
};
}
private void BuildSellLogData(dynamic rawSellLogData)
{
foreach (var rsld in rawSellLogData.data)
@ -399,10 +476,13 @@ namespace Core.Main.DataObjects
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
dtDateTime = dtDateTime.AddSeconds((double)rsld.soldDate).ToUniversalTime();
// Profit Trailer sales are saved in UTC
DateTimeOffset ptSoldDate = DateTimeOffset.Parse(dtDateTime.Year.ToString() + "-" + dtDateTime.Month.ToString("00") + "-" + dtDateTime.Day.ToString("00") + "T" + dtDateTime.Hour.ToString("00") + ":" + dtDateTime.Minute.ToString("00") + ":" + dtDateTime.Second.ToString("00"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
// Convert UTC sales time to local offset time
ptSoldDate = ptSoldDate.ToOffset(OffsetTimeSpan);
sellLogData.SoldDate = ptSoldDate.DateTime;
@ -424,7 +504,6 @@ namespace Core.Main.DataObjects
// Parse watch only pairs data
_dcaLog.AddRange(ParsePairsData(rawWatchModeLogData, false));
}
// Parse the pairs data from PT to our own common data structure.

View File

@ -872,7 +872,7 @@ namespace Core.Main
this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version);
// Get latest main fiat currency exchange rate
this.GetMainFiatCurrencyDetails();
// this.GetMainFiatCurrencyDetails();
// Load current PT files
this.LoadCurrentProfitTrailerProperties();
@ -1127,10 +1127,10 @@ namespace Core.Main
}
}
private void GetMainFiatCurrencyDetails()
{
this.LastRuntimeSummary.MainFiatCurrency = this.LastMainFiatCurrency;
this.LastRuntimeSummary.MainFiatCurrencyExchangeRate = this.LastMainFiatCurrencyExchangeRate;
//private void GetMainFiatCurrencyDetails()
//{
//this.LastRuntimeSummary.MainFiatCurrency = this.PropertiesData.Currency;
//this.LastRuntimeSummary.MainFiatCurrencyExchangeRate = this.LastMainFiatCurrencyExchangeRate;
// if (this.LastFiatCurrencyCheck < DateTime.UtcNow.AddHours(-12) && !this.PTMagicConfiguration.GeneralSettings.Application.MainFiatCurrency.Equals("USD", StringComparison.InvariantCultureIgnoreCase))
// {
@ -1154,7 +1154,7 @@ namespace Core.Main
// this.LastMainFiatCurrencyExchangeRate = 1;
// }
// }
}
//}
// Get current PT properties
private void LoadCurrentProfitTrailerProperties()

View File

@ -33,6 +33,11 @@
$("#baglist-refresh-icon").html('<i class="fa fa-circle-o-notch fa-spin fa-fw" data-toggle="tooltip" data-placement="top" title="Loading fresh data..."></i>');
$("#buylist-refresh-icon").html('<i class="fa fa-circle-o-notch fa-spin fa-fw" data-toggle="tooltip" data-placement="top" title="Loading fresh data..."></i>');
// Add the page refresh code here
setTimeout(function(){
location.reload();
}, 60 * 60 * 1000); // 60 minutes
// Clear exisitng interval to stop multiple attempts to load at the same time.
if (intervalDashboardTop != null)
{
@ -64,13 +69,13 @@
var loadDashboardBottom = function () {
//destroy all d3 svg graph to avoid memory leak
$(".nvtooltip").remove();
$("svg > *").remove();
$("svg").remove();
nv.charts = {};
nv.graphs = [];
nv.logs = {};
nv.tooltip = {};
//$(".nvtooltip").remove();
//$("svg > *").remove();
//$("svg").remove();
//nv.charts = {};
//nv.graphs = [];
//nv.logs = {};
//nv.tooltip = {};
// Clear exisitng interval to stop multiple attempts to load at the same time.
if (intervalDashboardBottom != null)

View File

@ -26,7 +26,7 @@
}
}
<th class="m-t-0 header-title text-left">Total Current Value: &nbsp; <text class="text-autocolor"> @totalCurrentValueString @Model.Summary.MainMarket </text> <small> <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This is based on the TCV reported by Profit Trailer."></i></small></th>
<th class="text-right">Starting Value: &nbsp; <text class="text-autocolor"> @Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance &nbsp; @Model.Summary.MainMarket </text> <small> <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This is the starting value found in your settings file"></i></small></th>
<th class="text-right">Starting Value: &nbsp; <text class="text-autocolor"> @Model.SummaryData.StartBalance &nbsp; @Model.Summary.MainMarket </text> <small> <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="This is the starting value found in your settings file"></i></small></th>
</tr>
</thead>
</table>
@ -64,7 +64,7 @@
double totalProfit = 0;
totalProfit = Model.PTData.SellLog.Sum(s => s.Profit);
double totalProfitFiat = Math.Round(totalProfit * Model.Summary.MainMarketPrice, 2);
double percentGain = Math.Round(totalProfit / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance * 100, 2);
double percentGain = Math.Round(totalProfit / Model.SummaryData.StartBalance * 100, 2);
double avgDailyGain = Model.DailyGains.Values.Average(dg => dg);
double avgMonthlyGain = Model.MonthlyGains.Values.Average(dg => dg);
string percentGainText = percentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%";

View File

@ -12,6 +12,7 @@ namespace Monitor.Pages
public class SalesAnalyzer : _Internal.BasePageModelSecure
{
public ProfitTrailerData PTData = null;
public SummaryData SummaryData { get; set; }
public string TradesChartDataJSON = "";
public string ProfitChartDataJSON = "";
public string BalanceChartDataJSON = "";
@ -31,6 +32,7 @@ namespace Monitor.Pages
private void BindData()
{
PTData = this.PtDataObject;
SummaryData = this.PTData.Summary;
// Convert local offset time to UTC
TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));

View File

@ -131,12 +131,12 @@
</div>
</div> *@
<div class="form-group row">
@* <div class="form-group row">
<label class="col-md-4 col-form-label">Starting Balance <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="PTM will use this to calculate total profits to date, and projected profits."></i></label>
<div class="col-md-8">
<input type="text" class="form-control" name="Application_StartBalance" value="@Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance">
<input type="text" class="form-control" name="Application_StartBalance" value="@Model.SummaryData.StartBalance">
</div>
</div>
</div> *@
<div class="form-group row">
<label class="col-md-4 col-form-label">CoinMarketCap API Key <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="The API Key that will be used to get Coin Data from CoinMarketCap (optional)."></i></label>

View File

@ -1,16 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Core.Main;
using Core.Helper;
using Core.Main.DataObjects;
using Core.Main.DataObjects.PTMagicData;
namespace Monitor.Pages
{
public class SettingsGeneralModel : _Internal.BasePageModelSecure
{
public string ValidationMessage = "";
public string ValidationMessage = "";
public ProfitTrailerData PTData = null;
public SummaryData SummaryData { get; set; }
private string GetTimezoneOffsetString(TimeZoneInfo tzi)
{
@ -51,6 +54,8 @@ namespace Monitor.Pages
public void OnGet()
{
base.Init();
PTData = this.PtDataObject;
SummaryData = this.PTData.Summary;
string notification = GetStringParameter("n", "");
if (notification.Equals("BackupRestored"))
@ -68,7 +73,7 @@ namespace Monitor.Pages
// Read the new settings
PTMagicConfiguration.GeneralSettings.Application.IsEnabled = HttpContext.Request.Form["Application_IsEnabled"].Equals("on");
PTMagicConfiguration.GeneralSettings.Application.TestMode = HttpContext.Request.Form["Application_TestMode"].Equals("on");
PTMagicConfiguration.GeneralSettings.Application.StartBalance = SystemHelper.TextToDouble(HttpContext.Request.Form["Application_StartBalance"], PTMagicConfiguration.GeneralSettings.Application.StartBalance, "en-US");
//PTMagicConfiguration.GeneralSettings.Application.StartBalance = SystemHelper.TextToDouble(HttpContext.Request.Form["Application_StartBalance"], PTMagicConfiguration.GeneralSettings.Application.StartBalance, "en-US");
PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerDefaultSettingName = HttpContext.Request.Form["Application_ProfitTrailerDefaultSettingName"];
PTMagicConfiguration.GeneralSettings.Application.Exchange = HttpContext.Request.Form["Application_Exchange"];
PTMagicConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL = HttpContext.Request.Form["Application_ProfitTrailerMonitorURL"];

View File

@ -24,7 +24,7 @@
</div>
<div class="col-md-3 px-1">
<div class="card-box px-3" style="height:305px;">
<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>*@
@{
string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"));
if (Model.totalCurrentValue > 100) {
@ -34,8 +34,8 @@
<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.PTMagicConfiguration.GeneralSettings.Application.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.PTMagicConfiguration.GeneralSettings.Application.StartBalance) / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) * 100, 2)%</text></span>
<span data-toggle="tooltip" data-placement="top" title="Starting balance from PTM settings">Start: &nbsp; <text class="text-autocolor"> @Model.SummaryData.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.SummaryData.StartBalance) / Model.SummaryData.StartBalance) * 100, 2)%</text></span>
</small>
</div>
<div class="text-center">
@ -49,7 +49,7 @@
</div>
<div class="col-md-4 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:305px;">
@if (!Model.ProfitChartDataJSON.Equals("")) {
<div class="profit-chart">
@ -61,6 +61,7 @@
</div>
</div>
</div>
<div class="row">
<div class="col-md-5 px-1">
<div class="card-box px-2">
@ -115,53 +116,58 @@
<div class="col-md-7 px-1">
<div class="card-box px-2">
<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>
<br>
@*<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>
<br>*@
<h4 class="m-t-0 m-b-20 header-title"><b>Sales Overview</b><small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)SalesAnalyzer">more</a></small></h4>
@{
var overviewStats = Model.StatsData.FirstOrDefault(); // todaysStats is a new variable
var overviewStats = Model.StatsData; // todaysStats is a new variable
var todaysSales = overviewStats.SalesToday;
var todaysProfit = overviewStats.ProfitToday;
var todaysFunding = overviewStats.FundingToday;
var todaysPercentGain = overviewStats.ProfitPercToday;
var todaysFundingGain = todaysPercentGain * ((todaysProfit - todaysFunding) / todaysProfit);
//var todaysFundingGain = todaysPercentGain * ((todaysProfit - todaysFunding) / todaysProfit);
var yesterdaysSales = overviewStats.SalesYesterday;
var yesterdaysProfit = overviewStats.ProfitYesterday;
var yesterdaysFunding = overviewStats.FundingYesterday;
var yesterdaysPercentGain = overviewStats.ProfitPercYesterday;
var yesterdaysFundingGain = yesterdaysPercentGain * ((yesterdaysProfit + yesterdaysFunding) / yesterdaysProfit);
//var yesterdaysFundingGain = yesterdaysPercentGain * ((yesterdaysProfit + yesterdaysFunding) / yesterdaysProfit);
var last7DaysSales = overviewStats.SalesWeek;
var last7DaysProfit = overviewStats.ProfitWeek;
var last7DaysFunding = overviewStats.FundingWeek;
var last7DaysPercentGain = overviewStats.ProfitPercWeek;
var last7DaysFundingGain = last7DaysPercentGain * ((last7DaysProfit + last7DaysFunding) / last7DaysProfit);
//var last7DaysFundingGain = last7DaysPercentGain * ((last7DaysProfit + last7DaysFunding) / last7DaysProfit);
var last30DaysSales = overviewStats.SalesMonth;
var last30DaysProfit = overviewStats.ProfitMonth;
var last30DaysFunding = overviewStats.FundingMonth;
var last30DaysPercentGain = overviewStats.ProfitPercMonth;
var last30DaysFundingGain = last30DaysPercentGain * ((last30DaysProfit + last30DaysFunding) / last30DaysProfit);
var thisMonthSales = overviewStats.SalesThisMonth;
var thisMonthProfit = overviewStats.ProfitThisMonth;
var thisMonthFunding = overviewStats.FundingThisMonth;
var thisMonthPercentGain = overviewStats.ProfitPercThisMonth;
//var thisMonthFundingGain = thisMonthPercentGain * ((thisMonthProfit + thisMonthFunding) / thisMonthProfit);
var lastMonthSales = overviewStats.SalesLastMonth;
var lastMonthProfit = overviewStats.ProfitLastMonth;
var lastMonthFunding = overviewStats.FundingLastMonth;
var lastMonthPercentGain = overviewStats.ProfitPercLastMonth;
//var lastMonthFundingGain = lastMonthPercentGain * ((lastMonthProfit + lastMonthFunding) / lastMonthProfit);
var totalSales = overviewStats.TotalSales;
var totalProfit = overviewStats.TotalProfit;
var totalFunding = overviewStats.FundingTotal;
var totalProfitPercent = overviewStats.TotalProfitPerc;
var totalFundingGain = totalProfitPercent * ((totalProfit + totalFunding) / totalProfit);
double todaysProfitFiat = Math.Round((todaysProfit + todaysFunding) * Model.Summary.MainMarketPrice, 2);
double yesterdaysProfitFiat = Math.Round((yesterdaysProfit + yesterdaysFunding) * Model.Summary.MainMarketPrice, 2);
double last7DaysProfitFiat = Math.Round((last7DaysProfit + last7DaysFunding) * Model.Summary.MainMarketPrice, 2);
double last30DaysProfitFiat = Math.Round((last30DaysProfit + last30DaysFunding) * Model.Summary.MainMarketPrice, 2);
double totalProfitFiat = Math.Round((totalProfit + totalFunding) * Model.Summary.MainMarketPrice, 2);
//var totalFundingGain = totalProfitPercent * ((totalProfit + totalFunding) / totalProfit);
double todaysProfitFiat = Math.Round((todaysProfit + todaysFunding) * Model.PTData.Summary.FiatConversionRate, 2);
double yesterdaysProfitFiat = Math.Round((yesterdaysProfit + yesterdaysFunding) * Model.PTData.Summary.FiatConversionRate, 2);
double last7DaysProfitFiat = Math.Round((last7DaysProfit + last7DaysFunding) * Model.PTData.Summary.FiatConversionRate, 2);
double thisMonthProfitFiat = Math.Round((thisMonthProfit + thisMonthFunding) * Model.PTData.Summary.FiatConversionRate, 2);
double lastMonthProfitFiat = Math.Round((lastMonthProfit + lastMonthFunding) * Model.PTData.Summary.FiatConversionRate, 2);
double totalProfitFiat = Math.Round((totalProfit + totalFunding) * Model.PTData.Summary.FiatConversionRate, 2);
bool futuresFunding = Model.PropertiesData.IsLeverageExchange;
}
<table class="table table-sm">
@ -169,10 +175,13 @@
<tr>
<th></th>
<th class="text-right">Sales</th>
<th class="text-right">Profit @Model.Summary.MainMarket</th>
<th class="text-right">Funding</th>
<th class="text-right">@Model.Summary.MainFiatCurrency</th>
<th class="text-right">Profit @Model.PTData.Summary.Market</th>
<th class="text-right">Gain</th>
@if (futuresFunding)
{
<th class="text-right">Funding</th>
}
<th class="text-right">@Model.PTData.Properties.Currency</th>
</tr>
</thead>
<tbody>
@ -180,41 +189,67 @@
<th>Today</th>
<td class="text-right">@overviewStats.SalesToday</td>
<td class="text-right text-autocolor">@todaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@todaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@todaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
@if (futuresFunding)
{
<td class="text-right text-autocolor">@todaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
}
<td class="text-right text-autocolor">@Html.Raw(todaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
<td class="text-right text-autocolor">@todaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
</tr>
<tr>
<th>Yesterday</th>
<td class="text-right">@yesterdaysSales</td>
<td class="text-right text-autocolor">@yesterdaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@yesterdaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@yesterdaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
@if (futuresFunding)
{
<td class="text-right text-autocolor">@yesterdaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
}
<td class="text-right text-autocolor">@Html.Raw(yesterdaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
<td class="text-right text-autocolor">@yesterdaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
</tr>
<tr>
<th>Last 7 Days</th>
<td class="text-right">@last7DaysSales</td>
<td class="text-right text-autocolor">@last7DaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@last7DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@last7DaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
@if (futuresFunding)
{
<td class="text-right text-autocolor">@last7DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
}
<td class="text-right text-autocolor">@Html.Raw(last7DaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
<td class="text-right text-autocolor">@last7DaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
</tr>
<tr>
<th>Last 30 Days</th>
<td class="text-right">@last30DaysSales</td>
<td class="text-right text-autocolor">@last30DaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@last30DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@Html.Raw(last30DaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
<td class="text-right text-autocolor">@last30DaysFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
<th>This Month</th>
<td class="text-right">@thisMonthSales</td>
<td class="text-right text-autocolor">@thisMonthProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@thisMonthPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
@if (futuresFunding)
{
<td class="text-right text-autocolor">@thisMonthFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
}
<td class="text-right text-autocolor">@Html.Raw(thisMonthProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
</tr>
<tr>
<th>Last Month</th>
<td class="text-right">@lastMonthSales</td>
<td class="text-right text-autocolor">@lastMonthProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@lastMonthPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
@if (futuresFunding)
{
<td class="text-right text-autocolor">@lastMonthFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
}
<td class="text-right text-autocolor">@Html.Raw(lastMonthProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
</tr>
<tr>
<th>Total</th>
<td class="text-right">@totalSales</td>
<td class="text-right text-autocolor">@totalProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@totalFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
<td class="text-right text-autocolor">@totalProfitPercent.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
@if (futuresFunding)
{
<td class="text-right text-autocolor">@totalFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
}
<td class="text-right text-autocolor">@Html.Raw(totalProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
<td class="text-right text-autocolor">@totalFundingGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
</tr>
</tbody>
</table>
@ -226,74 +261,101 @@
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/nvd3/nv.d3.min.js"></script>
<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 type="text/javascript">
$(document).ready(function () {
$(".cdev").circlos();
$('[data-toggle="tooltip"]').tooltip();
$('.text-autocolor').autocolor(false);
$(document).ready(function () {
$(".cdev").circlos();
$('[data-toggle="tooltip"]').tooltip();
$('.text-autocolor').autocolor(false);
var assetDistributionChart; // Keep a reference to the chart
var assetDistributionData; // Keep a reference to the data
@if (!Model.AssetDistributionData.Equals("")) {
<text>
nv.addGraph(function() {
assetDistributionChart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.showLabels(true)
.labelThreshold(.1)
.labelType("percent")
.donut(true)
.donutRatio(0.3);
assetDistributionData = @Html.Raw(Model.AssetDistributionData);
@if (!Model.AssetDistributionData.Equals("")) {
<text>
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.showLabels(true) //Display pie labels
.labelThreshold(.1) //Configure the minimum slice size for labels to show up
.labelType("percent") //Configure what type of data to show in the label. Can be "key", "value" or "percent"
.donut(true) //Turn on Donut mode. Makes pie chart look tasty!
.donutRatio(0.3) //Configure how big you want the donut hole size to be.
;
d3.select("#AssetDistribution svg")
.datum(@Html.Raw(Model.AssetDistributionData))
.transition().duration(350)
.call(chart);
return chart;
.datum(assetDistributionData)
.transition().duration(0)
.call(assetDistributionChart);
return assetDistributionChart;
});
</text>
}
});
</text>
}
});
</script>
<script type="text/javascript">
(function ($) {
'use strict';
$('[role="tooltip"]').remove();
$('[data-toggle="tooltip"]').tooltip();
$('.text-autocolor').autocolor(false);
@if (!Model.Summary.CurrentGlobalSetting.SettingName.Equals(Model.LastGlobalSetting)) {
<text>
$.Notification.notify('success', 'top left', '@Core.Helper.SystemHelper.SplitCamelCase(Model.Summary.CurrentGlobalSetting.SettingName) now active!', 'PTMagic switched Profit Trailer settings to "@Core.Helper.SystemHelper.SplitCamelCase(Model.Summary.CurrentGlobalSetting.SettingName)".');
</text>
}
var trendChart; // Keep a reference to the chart
var trendData; // Keep a reference to the data
@if (!Model.TrendChartDataJSON.Equals("")) {
<text>
nv.addGraph(function () {
var lineChart = nv.models.lineChart();
var height = 300;
var chartData = @Html.Raw(Model.TrendChartDataJSON);
lineChart.useInteractiveGuideline(true);
lineChart.xAxis.tickFormat(function (d) { return d3.time.format('%H:%M')(new Date(d)); });
lineChart.yAxis.axisLabel('Trend %').tickFormat(d3.format(',.2f'));
d3.select('.trend-chart svg').attr('perserveAspectRatio', 'xMinYMid').datum(chartData).transition().duration(500).call(lineChart);
//nv.utils.windowResize(lineChart.update); v1.3.0 => Removed this line to prevent memory leak
return lineChart;
<text>
nv.addGraph(function () {
trendChart = nv.models.lineChart();
var height = 300;
trendChart.useInteractiveGuideline(true);
trendChart.xAxis.tickFormat(function (d) { return d3.time.format('%H:%M')(new Date(d)); });
trendChart.yAxis.axisLabel('Trend %').tickFormat(d3.format(',.2f'));
trendData = @Html.Raw(Model.TrendChartDataJSON);
d3.select('.trend-chart svg')
.datum(trendData)
.transition().duration(0)
.call(trendChart);
return trendChart;
});
</text>
</text>
}
@if (!Model.ProfitChartDataJSON.Equals("")) {
<text>
nv.addGraph(function () {
var lineChart = nv.models.lineChart();
var height = 300;
var chartData = @Html.Raw(Model.ProfitChartDataJSON);
lineChart.useInteractiveGuideline(true);
lineChart.xAxis.tickFormat(function (d) { return d3.time.format('%Y/%m/%d')(new Date(d)); });
lineChart.yAxis.axisLabel('Daily Profit').tickFormat(d3.format(',.2f'));
d3.select('.profit-chart svg').attr('perserveAspectRatio', 'xMinYMid').datum(chartData).transition().duration(500).call(lineChart);
//nv.utils.windowResize(lineChart.update); v1.3.0 => Removed this line to prevent memory leak
return lineChart;
});
</text>
}
})(jQuery);
})(jQuery);
</script>
<script type="text/javascript">
(function ($) {
'use strict';
$('[role="tooltip"]').remove();
$('[data-toggle="tooltip"]').tooltip();
$('.text-autocolor').autocolor(false);
var profitChart; // Keep a reference to the chart
var profitData; // Keep a reference to the data
@if (!Model.ProfitChartDataJSON.Equals("")) {
<text>
nv.addGraph(function () {
profitChart = nv.models.lineChart();
var height = 300;
profitChart.useInteractiveGuideline(true);
profitChart.xAxis.tickFormat(function (d) { return d3.time.format('%Y/%m/%d')(new Date(d)); });
profitChart.yAxis.axisLabel('Daily Profit').tickFormat(d3.format(',.2f'));
profitData = @Html.Raw(Model.ProfitChartDataJSON);
d3.select('.profit-chart svg')
.datum(profitData)
.transition().duration(0)
.call(profitChart);
return profitChart;
});
</text>
}
})(jQuery);
</script>

View File

@ -6,14 +6,19 @@ using Core.Main;
using Core.Helper;
using Core.Main.DataObjects;
using Core.Main.DataObjects.PTMagicData;
using Core.MarketAnalyzer;
using System.Globalization;
using System.Text;
namespace Monitor.Pages
{
public class DashboardBottomModel : _Internal.BasePageModelSecureAJAX
{
public ProfitTrailerData PTData = null;
public List<StatsData> StatsData { get; set; }
public StatsData StatsData { get; set; }
public PropertiesData PropertiesData { 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 string TrendChartDataJSON = "";
public string ProfitChartDataJSON = "";
@ -35,6 +40,10 @@ namespace Monitor.Pages
{
PTData = this.PtDataObject;
StatsData = this.PTData.Stats;
PropertiesData = this.PTData.Properties;
SummaryData = this.PTData.Summary;
List<DailyStatsData> dailyStatsData = this.PTData.DailyStats;
List<DailyPNLData> dailyPNLData = this.PTData.DailyPNL;
// Cleanup temp files
FileHelper.CleanupFilesMinutes(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar, 5);
@ -57,110 +66,101 @@ namespace Monitor.Pages
BuildProfitChartData();
}
private void BuildMarketTrendChartData()
{
StringBuilder trendChartDataJSON = new StringBuilder();
if (MarketTrends.Count > 0)
{
if (MarketTrends.Count > 0)
{
TrendChartDataJSON = "[";
trendChartDataJSON.Append("[");
int mtIndex = 0;
foreach (MarketTrend mt in MarketTrends)
{
if (mt.DisplayGraph)
{
string lineColor = "";
if (mtIndex < Constants.ChartLineColors.Length)
if (mt.DisplayGraph)
{
lineColor = Constants.ChartLineColors[mtIndex];
}
else
{
lineColor = Constants.ChartLineColors[mtIndex - 20];
}
if (Summary.MarketTrendChanges.ContainsKey(mt.Name))
{
List<MarketTrendChange> marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name];
if (marketTrendChangeSummaries.Count > 0)
{
if (!TrendChartDataJSON.Equals("[")) TrendChartDataJSON += ",";
TrendChartDataJSON += "{";
TrendChartDataJSON += "key: '" + SystemHelper.SplitCamelCase(mt.Name) + "',";
TrendChartDataJSON += "color: '" + lineColor + "',";
TrendChartDataJSON += "values: [";
// Get trend ticks for chart
DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0);
DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours);
DateTime endDateTime = currentDateTime;
int trendChartTicks = 0;
for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes))
string lineColor = "";
if (mtIndex < Constants.ChartLineColors.Length)
{
List<MarketTrendChange> tickRange = marketTrendChangeSummaries.FindAll(m => m.TrendDateTime >= tickTime).OrderBy(m => m.TrendDateTime).ToList();
if (tickRange.Count > 0)
{
MarketTrendChange mtc = tickRange.First();
if (tickTime != startDateTime) TrendChartDataJSON += ",\n";
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
TrendChartDataJSON += "{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}";
trendChartTicks++;
}
lineColor = Constants.ChartLineColors[mtIndex];
}
// Add most recent tick
List<MarketTrendChange> latestTickRange = marketTrendChangeSummaries.OrderByDescending(m => m.TrendDateTime).ToList();
if (latestTickRange.Count > 0)
else
{
MarketTrendChange mtc = latestTickRange.First();
if (trendChartTicks > 0) TrendChartDataJSON += ",\n";
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
TrendChartDataJSON += "{ x: new Date('" + mtc.TrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}";
lineColor = Constants.ChartLineColors[mtIndex - 20];
}
if (Summary.MarketTrendChanges.ContainsKey(mt.Name))
{
List<MarketTrendChange> marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name];
if (marketTrendChangeSummaries.Count > 0)
{
if (!trendChartDataJSON.ToString().Equals("[")) trendChartDataJSON.Append(",");
trendChartDataJSON.Append("{");
trendChartDataJSON.Append("key: '" + SystemHelper.SplitCamelCase(mt.Name) + "',");
trendChartDataJSON.Append("color: '" + lineColor + "',");
trendChartDataJSON.Append("values: [");
// Get trend ticks for chart
DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0);
DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours);
DateTime endDateTime = currentDateTime;
int trendChartTicks = 0;
for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes))
{
List<MarketTrendChange> tickRange = marketTrendChangeSummaries.FindAll(m => m.TrendDateTime >= tickTime).OrderBy(m => m.TrendDateTime).ToList();
if (tickRange.Count > 0)
{
MarketTrendChange mtc = tickRange.First();
if (tickTime != startDateTime) trendChartDataJSON.Append(",\n");
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
trendChartDataJSON.Append("{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}");
trendChartTicks++;
}
}
// Add most recent tick
List<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 += "]";
TrendChartDataJSON += "}";
mtIndex++;
}
}
}
}
TrendChartDataJSON += "]";
}
trendChartDataJSON.Append("]");
}
TrendChartDataJSON = trendChartDataJSON.ToString();
}
private void BuildProfitChartData()
{
int tradeDayIndex = 0;
string profitPerDayJSON = "";
StringBuilder profitPerDayJSON = new StringBuilder();
if (PTData.SellLog.Count > 0)
{
DateTime minSellLogDate = PTData.SellLog.OrderBy(sl => sl.SoldDate).First().SoldDate.Date;
DateTime graphStartDate = DateTime.UtcNow.Date.AddDays(-30);
if (minSellLogDate > graphStartDate)
if (PTData.DailyStats.Count > 0)
{
graphStartDate = minSellLogDate;
DateTime endDate = DateTime.UtcNow.Date;
DateTime startDate = endDate.AddDays(-30);
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
if (profitPerDayJSON.Length > 0)
{
profitPerDayJSON.Append(",\n");
}
DailyStatsData dailyStats = PTData.DailyStats.Find(ds => DateTime.ParseExact(ds.Date, "d-M-yyyy", CultureInfo.InvariantCulture) == date);
double profitFiat = dailyStats != null ? Math.Round(dailyStats.TotalProfitCurrency,2) : 0;
profitPerDayJSON.Append("{x: new Date('" + date.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}");
}
ProfitChartDataJSON = "[{key: 'Profit in " + PTData.Properties.Currency + "',color: '" + Constants.ChartLineColors[1] + "',values: [" + profitPerDayJSON.ToString() + "]}]";
}
for (DateTime salesDate = graphStartDate; salesDate <= DateTime.UtcNow.Date; salesDate = salesDate.AddDays(1))
{
if (tradeDayIndex > 0)
{
profitPerDayJSON += ",\n";
}
int trades = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate).Count;
double profit = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate).Sum(t => t.Profit);
double profitFiat = Math.Round(profit * Summary.MainMarketPrice, 2);
profitPerDayJSON += "{x: new Date('" + salesDate.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}";
tradeDayIndex++;
}
ProfitChartDataJSON = "[";
ProfitChartDataJSON += "{";
ProfitChartDataJSON += "key: 'Profit in " + Summary.MainFiatCurrency + "',";
ProfitChartDataJSON += "color: '" + Constants.ChartLineColors[1] + "',";
ProfitChartDataJSON += "values: [" + profitPerDayJSON + "]";
ProfitChartDataJSON += "}";
ProfitChartDataJSON += "]";
}
}
private void BuildAssetDistributionData()
{
// the per PT-Eelroy, the PT API doesn't provide these values when using leverage, so they are calculated here to cover either case.
@ -171,9 +171,9 @@ namespace Monitor.Pages
bool isSellStrategyTrue = false;
bool isTrailingSellActive = false;
foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog)
{
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog)
{
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
// Aggregate totals
double leverage = dcaLogEntry.Leverage;

View File

@ -10,7 +10,6 @@
"ProfitTrailerMonitorURLXtra": "", // URLs for additional bots you want PTM to update (optional - comma separated list)
"ProfitTrailerDefaultSettingName": "default", // Your Profit Trailer default setting name (needed to change your settings)
"Exchange": "Bittrex", // The exchange your are running Profit Trailer on
"StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer
"TimezoneOffset": "+0:00", // Your timezone offset from UTC time
//"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor
"FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute

View File

@ -10,7 +10,6 @@
"ProfitTrailerMonitorURLXtra": "", // URLs for additional bots you want PTM to update (optional - comma separated list)
"ProfitTrailerDefaultSettingName": "default", // Your Profit Trailer default setting name (needed to change your settings)
"Exchange": "Bittrex", // The exchange your are running Profit Trailer on
"StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer
"TimezoneOffset": "+0:00", // Your timezone offset from UTC time
//"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor
"FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute