Sales Analyzer Top Markets
This commit is contained in:
parent
615e07986b
commit
b6b8647f21
|
@ -467,7 +467,13 @@ namespace Core.Main.DataObjects.PTMagicData
|
||||||
public double TotalSales { get; set; }
|
public double TotalSales { get; set; }
|
||||||
public double AvgGrowth { get; set; }
|
public double AvgGrowth { get; set; }
|
||||||
public double Order { get; set; }
|
public double Order { get; set; }
|
||||||
|
}
|
||||||
|
public class ProfitablePairsData
|
||||||
|
{
|
||||||
|
public string Coin { get; set; }
|
||||||
|
public double ProfitCurrency { get; set; }
|
||||||
|
public int SoldTimes { get; set; }
|
||||||
|
public double Avg { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PTStrategy
|
public class PTStrategy
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Core.Main.DataObjects
|
||||||
private List<DailyPNLData> _dailyPNL = new List<DailyPNLData>();
|
private List<DailyPNLData> _dailyPNL = new List<DailyPNLData>();
|
||||||
private List<DailyTCVData> _dailyTCV = new List<DailyTCVData>();
|
private List<DailyTCVData> _dailyTCV = new List<DailyTCVData>();
|
||||||
private List<MonthlyStatsData> _monthlyStats = new List<MonthlyStatsData>();
|
private List<MonthlyStatsData> _monthlyStats = new List<MonthlyStatsData>();
|
||||||
|
private List<ProfitablePairsData> _profitablePairs = new List<ProfitablePairsData>();
|
||||||
private decimal? _totalProfit = null;
|
private decimal? _totalProfit = null;
|
||||||
public decimal? TotalProfit
|
public decimal? TotalProfit
|
||||||
{
|
{
|
||||||
|
@ -48,6 +49,7 @@ namespace Core.Main.DataObjects
|
||||||
private DateTime _dcaLogRefresh = DateTime.UtcNow;
|
private DateTime _dcaLogRefresh = DateTime.UtcNow;
|
||||||
private DateTime _miscRefresh = DateTime.UtcNow;
|
private DateTime _miscRefresh = DateTime.UtcNow;
|
||||||
private DateTime _propertiesRefresh = DateTime.UtcNow;
|
private DateTime _propertiesRefresh = DateTime.UtcNow;
|
||||||
|
private DateTime _profitablePairsRefresh = DateTime.UtcNow;
|
||||||
private volatile object _dailyPNLLock = new object();
|
private volatile object _dailyPNLLock = new object();
|
||||||
private volatile object _dailyTCVLock = new object();
|
private volatile object _dailyTCVLock = new object();
|
||||||
private volatile object _monthlyStatsLock = new object();
|
private volatile object _monthlyStatsLock = new object();
|
||||||
|
@ -56,7 +58,8 @@ namespace Core.Main.DataObjects
|
||||||
private volatile object _sellLock = new object();
|
private volatile object _sellLock = new object();
|
||||||
private volatile object _dcaLock = new object();
|
private volatile object _dcaLock = new object();
|
||||||
private volatile object _miscLock = new object();
|
private volatile object _miscLock = new object();
|
||||||
private volatile object _propertiesLock = new object();
|
private volatile object _propertiesLock = new object();
|
||||||
|
private volatile object _profitablePairsLock = new object();
|
||||||
private TimeSpan? _offsetTimeSpan = null;
|
private TimeSpan? _offsetTimeSpan = null;
|
||||||
public void DoLog(string message)
|
public void DoLog(string message)
|
||||||
{
|
{
|
||||||
|
@ -305,6 +308,90 @@ namespace Core.Main.DataObjects
|
||||||
Order = dailyPNLDataJson["order"],
|
Order = dailyPNLDataJson["order"],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
public List<ProfitablePairsData> ProfitablePairs
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_profitablePairs == null || DateTime.UtcNow > _profitablePairsRefresh)
|
||||||
|
{
|
||||||
|
lock (_profitablePairsLock)
|
||||||
|
{
|
||||||
|
if (_profitablePairs == null || DateTime.UtcNow > _profitablePairsRefresh)
|
||||||
|
{
|
||||||
|
using (var stream = GetDataFromProfitTrailerAsStream("/api/v2/data/stats"))
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
using (var jsonReader = new JsonTextReader(reader))
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
JObject profitablePairsSection = (JObject)extraSection["profitablePairs"];
|
||||||
|
_profitablePairs = new List<ProfitablePairsData>();
|
||||||
|
int counter = 0;
|
||||||
|
foreach (var j in profitablePairsSection)
|
||||||
|
{
|
||||||
|
if (counter >= _systemConfiguration.GeneralSettings.Monitor.MaxTopMarkets)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Process each JObject in the dictionary
|
||||||
|
JObject profitablePair = (JObject)j.Value;
|
||||||
|
_profitablePairs.Add(BuildProfitablePairs(profitablePair));
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
_profitablePairsRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _profitablePairs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private ProfitablePairsData BuildProfitablePairs(JObject profitablePairsJson)
|
||||||
|
{
|
||||||
|
return new ProfitablePairsData()
|
||||||
|
{
|
||||||
|
Coin = profitablePairsJson["coin"].Value<string>(),
|
||||||
|
ProfitCurrency = profitablePairsJson["profitCurrency"].Value<double>(),
|
||||||
|
SoldTimes = profitablePairsJson["soldTimes"].Value<int>(),
|
||||||
|
Avg = profitablePairsJson["avg"].Value<double>(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public List<DailyTCVData> DailyTCV
|
public List<DailyTCVData> DailyTCV
|
||||||
|
@ -493,7 +580,7 @@ namespace Core.Main.DataObjects
|
||||||
this.BuildSellLogData(sellDataPage);
|
this.BuildSellLogData(sellDataPage);
|
||||||
pageIndex++;
|
pageIndex++;
|
||||||
requestedPages++;
|
requestedPages++;
|
||||||
Console.WriteLine($"Importing sale: {pageIndex}");
|
Console.WriteLine($"Importing sale: {pageIndex}");
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -219,8 +219,49 @@
|
||||||
<p>Unable to load graph, no sales data found.</p>
|
<p>Unable to load graph, no sales data found.</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="card-box">
|
||||||
|
<h4 class="m-t-0 header-title"><b>Top @Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxTopMarkets Sales Markets</b></h4>
|
||||||
|
<table class="tablesaw table m-b-0" data-tablesaw-sortable data-tablesaw-sortable-switch>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" data-tablesaw-priority="persist" data-tablesaw-sortable-col data-tablesaw-sortable-default-col>Rank</th>
|
||||||
|
<th scope="col" data-tablesaw-sortable-col>Market</th>
|
||||||
|
<th scope="col" class="text-right" data-tablesaw-sortable-col>Profit @Model.PTData.Misc.Market</th>
|
||||||
|
<th scope="col" class="text-right" data-tablesaw-sortable-col>Sales</th>
|
||||||
|
<th scope="col" class="text-right" data-tablesaw-sortable-col>Avg/Trade</th>
|
||||||
|
<th scope="col" class="text-right" data-tablesaw-sortable-col>Profit @Model.PTData.Properties.Currency</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@{
|
||||||
|
int rank = 1;
|
||||||
|
foreach (var pair in Model.ProfitablePairs)
|
||||||
|
{
|
||||||
|
string coin = pair.Coin;
|
||||||
|
double profit = Math.Round(pair.ProfitCurrency,8);
|
||||||
|
int sales = pair.SoldTimes;
|
||||||
|
double avg = Math.Round(pair.Avg,8);
|
||||||
|
double profitFiat = Math.Round(profit * Model.MiscData.FiatConversionRate, 0);
|
||||||
|
<tr>
|
||||||
|
<td>@rank</td>
|
||||||
|
<td><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, coin, Model.PTData.Misc.Market)" target="_blank">@coin</a></td>
|
||||||
|
<td class="text-right text-autocolor-saw">@profit</td>
|
||||||
|
<td class="text-right">@sales</td>
|
||||||
|
<td class="text-right text-autocolor-saw">@avg </td>
|
||||||
|
<td class="text-right text-autocolor-saw">@profitFiat</td>
|
||||||
|
</tr>
|
||||||
|
rank++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -315,55 +356,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="card-box">
|
|
||||||
<h4 class="m-t-0 header-title"><b>Top @Model.PTMagicConfiguration.GeneralSettings.Monitor.MaxTopMarkets Sales Market Analysis</b></h4>
|
|
||||||
<table class="tablesaw table m-b-0" data-tablesaw-sortable data-tablesaw-sortable-switch>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col" data-tablesaw-priority="persist" data-tablesaw-sortable-col data-tablesaw-sortable-default-col>Rank</th>
|
|
||||||
<th scope="col" data-tablesaw-sortable-col>Market</th>
|
|
||||||
<th scope="col" class="text-right" data-tablesaw-sortable-col>Sales</th>
|
|
||||||
<th scope="col" class="text-right" data-tablesaw-sortable-col>Profit @Model.Summary.MainMarket</th>
|
|
||||||
<th scope="col" class="text-right" data-tablesaw-sortable-col>Profit @Model.Summary.MainFiatCurrency</th>
|
|
||||||
<th scope="col" class="text-right" data-tablesaw-sortable-col>Profit @Model.Summary.MainFiatCurrency/Trade</th>
|
|
||||||
<th scope="col" class="text-right" data-tablesaw-sortable-col>Profit %/Trade</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@{
|
|
||||||
var topMarkets = Model.PTData.SellLog.GroupBy(m => m.Market).Select(mg => mg.Sum(m => m.Profit));
|
|
||||||
int marketRank = 0;
|
|
||||||
}
|
|
||||||
@foreach (KeyValuePair<string, double> marketData in Model.TopMarkets) {
|
|
||||||
marketRank++;
|
|
||||||
int trades = Model.PTData.SellLog.FindAll(m => m.Market == marketData.Key).Count;
|
|
||||||
double profitFiat = Math.Round(marketData.Value * Model.Summary.MainMarketPrice, 2);
|
|
||||||
double profitFiatPerTrade = Math.Round(profitFiat / trades, 2);
|
|
||||||
<tr>
|
|
||||||
<td>@marketRank</td>
|
|
||||||
<td><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform, Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, marketData.Key, Model.Summary.MainMarket)" target="_blank">@marketData.Key</a></td>
|
|
||||||
<td class="text-right">@trades</td>
|
|
||||||
<td class="text-right text-autocolor-saw">@marketData.Value.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
||||||
<td class="text-right text-autocolor-saw">@profitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainFiatCurrency</td>
|
|
||||||
<td class="text-right text-autocolor-saw">@profitFiatPerTrade.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) @Model.Summary.MainFiatCurrency</td>
|
|
||||||
<td class="text-right text-autocolor-saw">@Model.PTData.SellLog.FindAll(m => m.Market == marketData.Key).Average(p => p.ProfitPercent).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"))%</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="salesList" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
|
@* <div id="salesList" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
|
||||||
<div class="modal-dialog modal-full">
|
<div class="modal-dialog modal-full">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>
|
<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>
|
||||||
</div><!-- /.modal-content -->
|
</div><!-- /.modal-content -->
|
||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
</div><!-- /.modal -->
|
</div><!-- /.modal --> *@
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
|
@ -402,34 +403,6 @@
|
||||||
nv.utils.windowResize(lineChart.update);
|
nv.utils.windowResize(lineChart.update);
|
||||||
return lineChart;
|
return lineChart;
|
||||||
});
|
});
|
||||||
@*
|
|
||||||
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);
|
|
||||||
return lineChart;
|
|
||||||
});
|
|
||||||
|
|
||||||
nv.addGraph(function () {
|
|
||||||
var lineChart = nv.models.lineChart();
|
|
||||||
var height = 400;
|
|
||||||
/**/
|
|
||||||
var chartData = @Html.Raw(Model.BalanceChartDataJSON);
|
|
||||||
/**/
|
|
||||||
lineChart.useInteractiveGuideline(true);
|
|
||||||
lineChart.xAxis.tickFormat(function (d) { return d3.time.format('%Y/%m/%d')(new Date(d)); });
|
|
||||||
lineChart.yAxis.axisLabel('Profit').tickFormat(d3.format(',.2f'));
|
|
||||||
d3.select('.balance-chart svg').attr('perserveAspectRatio', 'xMinYMid').datum(chartData).transition().duration(500).call(lineChart);
|
|
||||||
nv.utils.windowResize(lineChart.update);
|
|
||||||
return lineChart;
|
|
||||||
}); *@
|
|
||||||
|
|
||||||
$("#salesList").on("show.bs.modal", function (e) {
|
$("#salesList").on("show.bs.modal", function (e) {
|
||||||
$(this).find(".modal-content").html('<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>');
|
$(this).find(".modal-content").html('<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>');
|
||||||
|
@ -481,6 +454,7 @@
|
||||||
d3.select('.nvtooltip').style('opacity', 0);
|
d3.select('.nvtooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nv.utils.windowResize(cumulativeProfitChart.update);
|
||||||
return cumulativeProfitChart;
|
return cumulativeProfitChart;
|
||||||
});
|
});
|
||||||
</text>
|
</text>
|
||||||
|
@ -528,6 +502,7 @@
|
||||||
d3.select('.nvtooltip').style('opacity', 0);
|
d3.select('.nvtooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nv.utils.windowResize(TCVChart.update);
|
||||||
return TCVChart;
|
return TCVChart;
|
||||||
});
|
});
|
||||||
</text>
|
</text>
|
||||||
|
@ -575,6 +550,7 @@
|
||||||
d3.select('.nvtooltip').style('opacity', 0);
|
d3.select('.nvtooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nv.utils.windowResize(profitChart.update);
|
||||||
return profitChart;
|
return profitChart;
|
||||||
});
|
});
|
||||||
</text>
|
</text>
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Monitor.Pages
|
||||||
public StatsData StatsData { get; set; }
|
public StatsData StatsData { get; set; }
|
||||||
public List<DailyPNLData> DailyPNL { get; set; }
|
public List<DailyPNLData> DailyPNL { get; set; }
|
||||||
public List<DailyTCVData> DailyTCV { get; set; }
|
public List<DailyTCVData> DailyTCV { get; set; }
|
||||||
|
public List<ProfitablePairsData> ProfitablePairs { get; set; }
|
||||||
public int ProfitDays { get; set; }
|
public int ProfitDays { get; set; }
|
||||||
public int TCVDays { get; set; }
|
public int TCVDays { get; set; }
|
||||||
public List<MonthlyStatsData> MonthlyStats { get; set; }
|
public List<MonthlyStatsData> MonthlyStats { get; set; }
|
||||||
|
@ -48,21 +49,16 @@ namespace Monitor.Pages
|
||||||
MonthlyStats = this.PTData.MonthlyStats;
|
MonthlyStats = this.PTData.MonthlyStats;
|
||||||
DailyPNL = this.PTData.DailyPNL;
|
DailyPNL = this.PTData.DailyPNL;
|
||||||
DailyTCV = this.PTData.DailyTCV;
|
DailyTCV = this.PTData.DailyTCV;
|
||||||
|
ProfitablePairs = this.PTData.ProfitablePairs;
|
||||||
|
|
||||||
//List<MonthlyStatsData> monthlyStatsData = this.PTData.MonthlyStats;
|
|
||||||
//List<DailyPNLData> dailyPNLData = this.PTData.DailyPNL;
|
|
||||||
|
|
||||||
|
|
||||||
// Convert local offset time to UTC
|
// Convert local offset time to UTC
|
||||||
TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
||||||
DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
|
DateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
|
||||||
|
|
||||||
BuildTopMarkets();
|
|
||||||
BuildSalesChartData();
|
BuildSalesChartData();
|
||||||
BuildProfitChartData();
|
BuildProfitChartData();
|
||||||
BuildCumulativeProfitChartData();
|
BuildCumulativeProfitChartData();
|
||||||
BuildTCVChartData();
|
BuildTCVChartData();
|
||||||
//MonthlyAverages(monthlyStatsData, PTData.Stats.FundingTotal);
|
|
||||||
}
|
}
|
||||||
private void BuildTCVChartData()
|
private void BuildTCVChartData()
|
||||||
{
|
{
|
||||||
|
@ -314,25 +310,14 @@ namespace Monitor.Pages
|
||||||
|
|
||||||
int tradeDayIndex = 0;
|
int tradeDayIndex = 0;
|
||||||
string tradesPerDayJSON = "";
|
string tradesPerDayJSON = "";
|
||||||
string profitPerDayJSON = "";
|
|
||||||
string balancePerDayJSON = "";
|
|
||||||
double balance = 0.0;
|
|
||||||
for (DateTime salesDate = graphStartDate; salesDate <= DateTimeNow.DateTime.Date; salesDate = salesDate.AddDays(1))
|
for (DateTime salesDate = graphStartDate; salesDate <= DateTimeNow.DateTime.Date; salesDate = salesDate.AddDays(1))
|
||||||
{
|
{
|
||||||
if (tradeDayIndex > 0)
|
if (tradeDayIndex > 0)
|
||||||
{
|
{
|
||||||
tradesPerDayJSON += ",\n";
|
tradesPerDayJSON += ",\n";
|
||||||
profitPerDayJSON += ",\n";
|
|
||||||
balancePerDayJSON += ",\n";
|
|
||||||
}
|
}
|
||||||
double profit = 0;
|
|
||||||
int trades = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Count;
|
int trades = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Count;
|
||||||
profit = PTData.SellLog.FindAll(t => t.SoldDate.Date == salesDate.Date).Sum(t => t.Profit);
|
|
||||||
double profitFiat = Math.Round(profit * Summary.MainMarketPrice, 2);
|
|
||||||
balance += profitFiat;
|
|
||||||
tradesPerDayJSON += "{x: new Date('" + salesDate.Date.ToString("yyyy-MM-dd") + "'), y: " + trades + "}";
|
tradesPerDayJSON += "{x: new Date('" + salesDate.Date.ToString("yyyy-MM-dd") + "'), y: " + trades + "}";
|
||||||
profitPerDayJSON += "{x: new Date('" + salesDate.Date.ToString("yyyy-MM-dd") + "'), y: " + profitFiat.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}";
|
|
||||||
balancePerDayJSON += "{x: new Date('" + salesDate.Date.ToString("yyyy-MM-dd") + "'), y: " + balance.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}";
|
|
||||||
tradeDayIndex++;
|
tradeDayIndex++;
|
||||||
}
|
}
|
||||||
TradesChartDataJSON = "[";
|
TradesChartDataJSON = "[";
|
||||||
|
@ -343,42 +328,7 @@ namespace Monitor.Pages
|
||||||
TradesChartDataJSON += "}";
|
TradesChartDataJSON += "}";
|
||||||
TradesChartDataJSON += "]";
|
TradesChartDataJSON += "]";
|
||||||
|
|
||||||
ProfitChartDataJSON = "[";
|
|
||||||
ProfitChartDataJSON += "{";
|
|
||||||
ProfitChartDataJSON += "key: 'Profit in " + Summary.MainFiatCurrency + "',";
|
|
||||||
ProfitChartDataJSON += "color: '" + Constants.ChartLineColors[1] + "',";
|
|
||||||
ProfitChartDataJSON += "values: [" + profitPerDayJSON + "]";
|
|
||||||
ProfitChartDataJSON += "}";
|
|
||||||
ProfitChartDataJSON += "]";
|
|
||||||
|
|
||||||
BalanceChartDataJSON = "[";
|
|
||||||
BalanceChartDataJSON += "{";
|
|
||||||
BalanceChartDataJSON += "key: 'Profit in " + Summary.MainFiatCurrency + "',";
|
|
||||||
BalanceChartDataJSON += "color: '" + Constants.ChartLineColors[1] + "',";
|
|
||||||
BalanceChartDataJSON += "values: [" + balancePerDayJSON + "]";
|
|
||||||
BalanceChartDataJSON += "}";
|
|
||||||
BalanceChartDataJSON += "]";
|
|
||||||
|
|
||||||
for (DateTime salesDate = DateTimeNow.DateTime.Date; salesDate >= MinSellLogDate; salesDate = salesDate.AddDays(-1))
|
|
||||||
{
|
|
||||||
List<SellLogData> salesDateSales = PTData.SellLog.FindAll(sl => sl.SoldDate.Date == salesDate);
|
|
||||||
double salesDateProfit;
|
|
||||||
salesDateProfit = salesDateSales.Sum(sl => sl.Profit);
|
|
||||||
double salesDateStartBalance = PTData.GetSnapshotBalance(salesDate);
|
|
||||||
double salesDateGain = Math.Round(salesDateProfit / salesDateStartBalance * 100, 2);
|
|
||||||
DailyGains.Add(salesDate, salesDateGain);
|
|
||||||
}
|
|
||||||
DateTime minSellLogMonthDate = new DateTime(MinSellLogDate.Year, MinSellLogDate.Month, 1).Date;
|
|
||||||
DateTime salesMonthStartDate = new DateTime(DateTimeNow.DateTime.Year, DateTimeNow.DateTime.Month, 1).Date;
|
|
||||||
for (DateTime salesMonthDate = salesMonthStartDate.Date; salesMonthDate >= minSellLogMonthDate; salesMonthDate = salesMonthDate.AddMonths(-1))
|
|
||||||
{
|
|
||||||
List<Core.Main.DataObjects.PTMagicData.SellLogData> salesMonthSales = PTData.SellLog.FindAll(sl => sl.SoldDate.Date.Month == salesMonthDate.Month && sl.SoldDate.Date.Year == salesMonthDate.Year);
|
|
||||||
double salesDateProfit;
|
|
||||||
salesDateProfit = salesMonthSales.Sum(sl => sl.Profit);
|
|
||||||
double salesDateStartBalance = PTData.GetSnapshotBalance(salesMonthDate);
|
|
||||||
double salesDateGain = Math.Round(salesDateProfit / salesDateStartBalance * 100, 2);
|
|
||||||
MonthlyGains.Add(salesMonthDate, salesDateGain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
<div class="col-md-4 px-1">
|
<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:320px;">
|
<div class="card-box px-2" style="height:340px;">
|
||||||
<h4 class="m-t-0 m-b-20 header-title" style="display: inline;"><b>Daily Profit </b><i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="@Model.ProfitDays days of data available. Currently Set to @Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays days in general settings."></i>
|
<h4 class="m-t-0 m-b-20 header-title" style="display: inline;"><b>Daily Profit </b><i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="@Model.ProfitDays days of data available. Currently Set to @Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays days in general settings."></i>
|
||||||
@if (!Model.ProfitChartDataJSON.Equals("")) {
|
@if (!Model.ProfitChartDataJSON.Equals("")) {
|
||||||
<div class="profit-chart">
|
<div class="profit-chart">
|
||||||
|
@ -308,7 +308,7 @@
|
||||||
d3.select('.nvtooltip').style('opacity', 0);
|
d3.select('.nvtooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nv.utils.windowResize(assetDistributionChart.update);
|
||||||
return assetDistributionChart;
|
return assetDistributionChart;
|
||||||
});
|
});
|
||||||
</text>
|
</text>
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
d3.select('.nvtooltip').style('opacity', 0);
|
d3.select('.nvtooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nv.utils.windowResize(trendChart.update);
|
||||||
return trendChart;
|
return trendChart;
|
||||||
});
|
});
|
||||||
</text>
|
</text>
|
||||||
|
@ -403,8 +403,7 @@
|
||||||
d3.select('.nvtooltip').style('opacity', 0);
|
d3.select('.nvtooltip').style('opacity', 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nv.utils.windowResize(profitChart.update);
|
||||||
|
|
||||||
return profitChart;
|
return profitChart;
|
||||||
});
|
});
|
||||||
</text>
|
</text>
|
||||||
|
|
Loading…
Reference in New Issue