Merge pull request #205 from HojouFotytu/develop

Level Forumulas, etc
This commit is contained in:
HojouFotytu 2020-07-19 01:01:54 +09:00 committed by GitHub
commit 139bf33df2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 186 additions and 118 deletions

View File

@ -464,6 +464,7 @@ namespace Core.Main.DataObjects.PTMagicData
public DateTime FirstBoughtDate { get; set; } public DateTime FirstBoughtDate { get; set; }
public string SellStrategy { get; set; } public string SellStrategy { get; set; }
public string BuyStrategy { get; set; } public string BuyStrategy { get; set; }
public double Leverage { get; set; }
public List<Strategy> BuyStrategies { get; set; } = new List<Strategy>(); public List<Strategy> BuyStrategies { get; set; } = new List<Strategy>();
public List<Strategy> SellStrategies { get; set; } = new List<Strategy>(); public List<Strategy> SellStrategies { get; set; } = new List<Strategy>();
} }

View File

@ -205,11 +205,7 @@ namespace Core.Main.DataObjects
public double GetCurrentBalance() public double GetCurrentBalance()
{ {
return return
(this.Summary.Balance + (this.Summary.Balance);
this.Summary.PairsValue +
this.Summary.DCAValue +
this.Summary.PendingValue +
this.Summary.DustValue);
} }
public double GetPairsBalance() public double GetPairsBalance()
{ {
@ -304,21 +300,13 @@ namespace Core.Main.DataObjects
sellLogData.AverageBuyPrice = rsld.avgPrice; sellLogData.AverageBuyPrice = rsld.avgPrice;
sellLogData.TotalCost = sellLogData.SoldAmount * sellLogData.AverageBuyPrice; sellLogData.TotalCost = sellLogData.SoldAmount * sellLogData.AverageBuyPrice;
// check if sale was a short position // check if bot is a shortbot via PT API. Losses on short bot currently showing as gains. Issue #195
if ((sellLogData.ProfitPercent > 0) && (sellLogData.AverageBuyPrice > sellLogData.SoldPrice)) // code removed
{
double soldValueRaw = (sellLogData.SoldAmount * sellLogData.SoldPrice);
double soldValueAfterFees = soldValueRaw + (soldValueRaw * ((double)rsld.fee / 100));
sellLogData.SoldValue = soldValueAfterFees;
sellLogData.Profit = Math.Abs(Math.Round(sellLogData.SoldValue - sellLogData.TotalCost, 8));
}
else
{
double soldValueRaw = (sellLogData.SoldAmount * sellLogData.SoldPrice); double soldValueRaw = (sellLogData.SoldAmount * sellLogData.SoldPrice);
double soldValueAfterFees = soldValueRaw - (soldValueRaw * ((double)rsld.fee / 100)); double soldValueAfterFees = soldValueRaw - (soldValueRaw * ((double)rsld.fee / 100));
sellLogData.SoldValue = soldValueAfterFees; sellLogData.SoldValue = soldValueAfterFees;
sellLogData.Profit = Math.Round(sellLogData.SoldValue - sellLogData.TotalCost, 8); sellLogData.Profit = Math.Round(sellLogData.SoldValue - sellLogData.TotalCost, 8);
}
//Convert Unix Timestamp to Datetime //Convert Unix Timestamp to Datetime
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc); System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
@ -373,6 +361,7 @@ namespace Core.Main.DataObjects
dcaLogData.CurrentPrice = pair.currentPrice; dcaLogData.CurrentPrice = pair.currentPrice;
dcaLogData.SellTrigger = pair.triggerValue == null ? 0 : pair.triggerValue; dcaLogData.SellTrigger = pair.triggerValue == null ? 0 : pair.triggerValue;
dcaLogData.PercChange = pair.percChange; dcaLogData.PercChange = pair.percChange;
dcaLogData.Leverage = pair.leverage == null ? 0 : pair.leverage;
dcaLogData.BuyStrategy = pair.buyStrategy == null ? "" : pair.buyStrategy; dcaLogData.BuyStrategy = pair.buyStrategy == null ? "" : pair.buyStrategy;
dcaLogData.SellStrategy = pair.sellStrategy == null ? "" : pair.sellStrategy; dcaLogData.SellStrategy = pair.sellStrategy == null ? "" : pair.sellStrategy;
dcaLogData.IsTrailing = false; dcaLogData.IsTrailing = false;

View File

@ -168,12 +168,9 @@ namespace Core.ProfitTrailer
boolean = boolean && nextBoolean; boolean = boolean && nextBoolean;
else else
boolean = boolean || nextBoolean; boolean = boolean || nextBoolean;
} }
return boolean; return boolean;
} }
throw new Exception("Empty expression"); throw new Exception("Empty expression");
} }
@ -227,8 +224,7 @@ namespace Core.ProfitTrailer
{ {
result = ""; result = "";
} }
// strategy labels that are variable value
// strategy labels that are variable, so can't be caught by the switch statement
if (result.Contains("REBUY")) if (result.Contains("REBUY"))
{ {
time = strategyName.Remove(0, 14); time = strategyName.Remove(0, 14);
@ -238,13 +234,18 @@ namespace Core.ProfitTrailer
{ {
result = "CHANGE"; result = "CHANGE";
} }
if (result.Contains("LEVERAGE")) if (result.Contains("CROSSED"))
{
leverage = strategyName.Remove(0, 9);
leverage = leverage.Remove(leverage.Length - 1, 1);
result = "CROSS " + leverage + "X";
}
if (result.Contains("ISOLATED"))
{ {
leverage = strategyName.Remove(0, 10); leverage = strategyName.Remove(0, 10);
leverage = leverage.Remove(leverage.Length - 1, 1); leverage = leverage.Remove(leverage.Length - 1, 1);
result = leverage + " X"; result = "ISOL " + leverage + "X";
} }
// buy/sell strategies beginning with PT 2.3.3 contain the strategy designation letter followed by a colon and space. // buy/sell strategies beginning with PT 2.3.3 contain the strategy designation letter followed by a colon and space.
// remove the letter and colon, change to shortcut, then reapply the letter and colon // remove the letter and colon, change to shortcut, then reapply the letter and colon
if (strategyName.Contains(":")) if (strategyName.Contains(":"))
@ -423,10 +424,21 @@ namespace Core.ProfitTrailer
case "no dca buy logic": case "no dca buy logic":
result = String.Concat(strategyLetter, "NODCA"); result = String.Concat(strategyLetter, "NODCA");
break; break;
case "combimagain":
result = String.Concat(strategyLetter, "COMBIG");
break;
case "combimaspread":
result = String.Concat(strategyLetter, "COMBIS");
break;
case "combimacross":
result = String.Concat(strategyLetter, "COMBIC");
break;
case "macdpercentage":
result = String.Concat(strategyLetter, "MACDPERC");
break;
default: default:
break; break;
} }
if (onlyValidStrategies) if (onlyValidStrategies)
{ {
if (strategyName.IndexOf("SOM") > -1 || strategyName.IndexOf("MAX") > -1 || strategyName.IndexOf("MIN") > -1 || strategyName.IndexOf("PRICE") > -1 || strategyName.IndexOf("BLACK") > -1 || strategyName.IndexOf("INSUFFICIENT") > -1 || strategyName.IndexOf("COST") > -1) if (strategyName.IndexOf("SOM") > -1 || strategyName.IndexOf("MAX") > -1 || strategyName.IndexOf("MIN") > -1 || strategyName.IndexOf("PRICE") > -1 || strategyName.IndexOf("BLACK") > -1 || strategyName.IndexOf("INSUFFICIENT") > -1 || strategyName.IndexOf("COST") > -1)
@ -434,7 +446,6 @@ namespace Core.ProfitTrailer
result = ""; result = "";
} }
} }
return result; return result;
} }
@ -446,14 +457,11 @@ namespace Core.ProfitTrailer
public static bool IsValidStrategy(string strategyName, bool checkForAnyInvalid) public static bool IsValidStrategy(string strategyName, bool checkForAnyInvalid)
{ {
bool result = false; bool result = false;
// buy/sell strategies beginning with PT 2.3.3 contain the letter followed by a colon and space. // buy/sell strategies beginning with PT 2.3.3 contain the letter followed by a colon and space.
if (strategyName.Contains(":")) if (strategyName.Contains(":"))
{ {
result = true; result = true;
} }
// Prior to PT 2.3.3
if (!checkForAnyInvalid) if (!checkForAnyInvalid)
{ {
switch (strategyName.ToLower()) switch (strategyName.ToLower())
@ -500,6 +508,10 @@ namespace Core.ProfitTrailer
case "vwappercentage": case "vwappercentage":
case "mvwappercentage": case "mvwappercentage":
case "btcdominance": case "btcdominance":
case "combimagain":
case "combimaspread":
case "combimacross":
case "macdpercentage":
result = true; result = true;
break; break;
default: default:
@ -522,14 +534,11 @@ namespace Core.ProfitTrailer
result = true; result = true;
} }
} }
return result; return result;
} }
public static int GetStrategyValueDecimals(string strategyName) public static int GetStrategyValueDecimals(string strategyName)
{ {
int result = 0; int result = 0;
switch (strategyName.ToLower()) switch (strategyName.ToLower())
{ {
case "lowbb": case "lowbb":
@ -568,10 +577,8 @@ namespace Core.ProfitTrailer
default: default:
break; break;
} }
return result; return result;
} }
public static string GetStrategyText(Summary summary, List<Strategy> strategies, string strategyText, bool isTrue, bool isTrailingBuyActive) public static string GetStrategyText(Summary summary, List<Strategy> strategies, string strategyText, bool isTrue, bool isTrailingBuyActive)
{ {
bool isValidStrategy = false; bool isValidStrategy = false;
@ -582,13 +589,43 @@ namespace Core.ProfitTrailer
foreach (Strategy strategy in strategies) foreach (Strategy strategy in strategies)
{ {
string textClass = (strategy.IsTrue) ? "label-success" : "label-danger"; string textClass = (strategy.IsTrue) ? "label-success" : "label-danger";
isValidStrategy = StrategyHelper.IsValidStrategy(strategy.Name); isValidStrategy = StrategyHelper.IsValidStrategy(strategy.Name);
if (!isValidStrategy) if (!isValidStrategy)
{ {
// Parse Formulas
if (strategy.Name.Contains("FORMULA") && !strategy.Name.Contains("STATS")) if (strategy.Name.Contains("TRIGGERED"))
// remove levels already triggered, to show only currently waiting trigger
{
strategyText += "";
}
else if (strategy.Name.Contains("STATS"))
// avoid parsing advanced buy stats
{
strategy.Name = "";
}
else if (strategy.Name.Contains("FORMULA"))
// Parse Various PT Formulas
{
if (strategy.Name.Contains("LEVEL"))
// level X
{
string level = strategy.Name.Substring(5, 2);
string expression = strategy.Name.Remove(0, 17);
expression = expression.Replace("<span class=\"tdgreen\">", "true").Replace("<span class=\"red\">", "false").Replace("</span>", "").Replace("&&", "and").Replace("||", "or");
expression = regx.Replace(expression, String.Empty);
var tokens = new Tokenizer(expression).Tokenize();
var parser = new Parser(tokens);
if (parser.Parse())
{
strategyText += "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"LEVEL FORMULA\">L " + level + "</span> ";
}
else
{
strategyText += "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"LEVEL FORMULA\">L " + level + "</span> ";
}
}
else
// standard formula
{ {
string expression = strategy.Name.Remove(0, 10); string expression = strategy.Name.Remove(0, 10);
expression = expression.Replace("<span class=\"tdgreen\">", "true").Replace("<span class=\"red\">", "false").Replace("</span>", "").Replace("&&", "and").Replace("||", "or"); expression = expression.Replace("<span class=\"tdgreen\">", "true").Replace("<span class=\"red\">", "false").Replace("</span>", "").Replace("&&", "and").Replace("||", "or");
@ -597,18 +634,19 @@ namespace Core.ProfitTrailer
var parser = new Parser(tokens); var parser = new Parser(tokens);
if (parser.Parse()) if (parser.Parse())
{ {
strategyText += "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">(FORM)</span> "; strategyText += "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">FORM</span> ";
} }
else else
{ {
strategyText += "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">(FORM)</span> "; strategyText += "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">FORM</span> ";
}
} }
} }
else else
{ {
strategyText += "<span class=\"label label-warning\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategy.Name + "\">" + StrategyHelper.GetStrategyShortcut(strategy.Name, false) + "</span> "; strategyText += "<span class=\"label label-warning\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategy.Name + "\">" + StrategyHelper.GetStrategyShortcut(strategy.Name, false) + "</span> ";
} }
} }
else else
{ {
@ -634,14 +672,11 @@ namespace Core.ProfitTrailer
} }
else else
{ {
isValidStrategy = StrategyHelper.IsValidStrategy(strategyText); isValidStrategy = StrategyHelper.IsValidStrategy(strategyText);
if (isValidStrategy) if (isValidStrategy)
{ {
strategyText = "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategyText + "\">" + StrategyHelper.GetStrategyShortcut(strategyText, true) + "</span>"; strategyText = "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategyText + "\">" + StrategyHelper.GetStrategyShortcut(strategyText, true) + "</span>";
} }
else if (strategyText.Equals("") && isValidStrategy == false) else if (strategyText.Equals("") && isValidStrategy == false)
{ {
strategyText = "<span class=\"label label-muted\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Not Applicable: Not using DCA!\"></span>"; strategyText = "<span class=\"label label-muted\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Not Applicable: Not using DCA!\"></span>";
@ -652,10 +687,8 @@ namespace Core.ProfitTrailer
} }
} }
} }
return strategyText; return strategyText;
} }
public static string GetCurrentValueText(List<Strategy> strategies, string strategyText, double bbValue, double simpleValue, bool includeShortcut) public static string GetCurrentValueText(List<Strategy> strategies, string strategyText, double bbValue, double simpleValue, bool includeShortcut)
{ {
string result = ""; string result = "";
@ -716,14 +749,12 @@ namespace Core.ProfitTrailer
result = simpleValue.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%"; result = simpleValue.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%";
} }
} }
return result; return result;
} }
public static string GetTriggerValueText(Summary summary, List<Strategy> strategies, string strategyText, double bbValue, double simpleValue, int buyLevel, bool includeShortcut) public static string GetTriggerValueText(Summary summary, List<Strategy> strategies, string strategyText, double bbValue, double simpleValue, int buyLevel, bool includeShortcut)
{ {
string result = ""; string result = "";
if (strategies.Count > 0) if (strategies.Count > 0)
{ {
foreach (Strategy strategy in strategies) foreach (Strategy strategy in strategies)
@ -738,12 +769,10 @@ namespace Core.ProfitTrailer
{ {
decimalFormat += "0"; decimalFormat += "0";
} }
if (includeShortcut) if (includeShortcut)
{ {
result += "<span class=\"text-muted\">" + StrategyHelper.GetStrategyShortcut(strategy.Name, true) + "</span> "; result += "<span class=\"text-muted\">" + StrategyHelper.GetStrategyShortcut(strategy.Name, true) + "</span> ";
} }
if (StrategyHelper.GetStrategyShortcut(strategy.Name, true).IndexOf("and", StringComparison.InvariantCultureIgnoreCase) > -1) if (StrategyHelper.GetStrategyShortcut(strategy.Name, true).IndexOf("and", StringComparison.InvariantCultureIgnoreCase) > -1)
{ {
result += strategy.TriggerValue.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")); result += strategy.TriggerValue.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
@ -787,7 +816,6 @@ namespace Core.ProfitTrailer
result = simpleValue.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%"; result = simpleValue.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%";
} }
} }
return result; return result;
} }
} }

View File

@ -10,10 +10,9 @@
} }
<div class="row"> <div class="row">
<div class="col-md-5 px-1"> <div class="col-md-4 px-1">
<div class="card-box px-2" style="height:305px;"> <div class="card-box px-2" 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>
@if (!Model.TrendChartDataJSON.Equals("")) { @if (!Model.TrendChartDataJSON.Equals("")) {
<div class="trend-chart"> <div class="trend-chart">
<svg style="height: 300px;width: 100%;"></svg> <svg style="height: 300px;width: 100%;"></svg>
@ -23,33 +22,27 @@
} }
</div> </div>
</div> </div>
<div class="col-md-2 px-1"> <div class="col-md-3 px-1">
<div class="card-box px-2" style="height:305px;"> <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>
@{ @{
double currentBalance = Model.PTData.GetCurrentBalance(); string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"));
string currentBalanceString = currentBalance.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US")); if (Model.totalCurrentValue > 100) {
if (currentBalance > 100) { totalCurrentValueString = Math.Round(Model.totalCurrentValue, 2).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
currentBalanceString = Math.Round(currentBalance, 2).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
} }
} }
<div class="text-center"> <div class="text-center"><small>TCV: &nbsp; <text class="text-autocolor"> @totalCurrentValueString &nbsp; @Model.Summary.MainMarket &nbsp; </text> </small></div>
<small>
Start balence: &nbsp; <text class="text-autocolor"> @Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance @Model.Summary.MainMarket</text>
<br>
Current value: &nbsp; <text class="text-autocolor"> @currentBalanceString @Model.Summary.MainMarket</text>
<br>
Gain: &nbsp; <text class="text-autocolor"> @Math.Round(((currentBalance - Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) * 100, 2) %</text>
</small>
</div>
<div id="AssetDistribution"> <div id="AssetDistribution">
<svg style="height:230px;width:100%"></svg> <svg style="height:230px;width:100%"></svg>
<div class="text">
<small>Start: &nbsp; <text class="text-autocolor"> @Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance @Model.Summary.MainMarket </text>
<text class="pull-right">Gain: &nbsp; <text class="text-autocolor"> @Math.Round(((Model.totalCurrentValue - Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) / Model.PTMagicConfiguration.GeneralSettings.Application.StartBalance) * 100, 2) %</text></small>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-5 px-1"> <div class="col-md-5 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;"> <div class="card-box px-2" style="height:305px;">
@if (!Model.ProfitChartDataJSON.Equals("")) { @if (!Model.ProfitChartDataJSON.Equals("")) {
<div class="profit-chart"> <div class="profit-chart">
@ -61,16 +54,13 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6 px-1"> <div class="col-md-6 px-1">
<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>
<div class="card-box px-2"> <div class="card-box px-2">
<br/> <div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>
<h4 class="m-t-0 m-b-20 header-title"><b>Market Trends at @Model.PTMagicConfiguration.GeneralSettings.Application.Exchange</b><small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)MarketAnalyzer">more</a></small></h4> <br>
<h4 class="m-t-0 m-b-20 header-title"><b>Market Trends at @Model.PTMagicConfiguration.GeneralSettings.Application.Exchange</b>
<small class="pull-right"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)MarketAnalyzer">more</a></small></h4>
<table class="table table-sm"> <table class="table table-sm">
<thead> <thead>
<tr> <tr>
@ -108,17 +98,17 @@
</div> </div>
<div class="col-md-6 px-1"> <div class="col-md-6 px-1">
<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>
<div class="card-box px-2"> <div class="card-box px-2">
<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> <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>
@{ @{
double totalProfit = Model.PTData.SellLog.Sum(s => s.Profit); double totalProfit = Model.PTData.SellLog.Sum(s => s.Profit);
double totalProfitFiat = Math.Round(totalProfit * Model.Summary.MainMarketPrice, 2); 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.PTMagicConfiguration.GeneralSettings.Application.StartBalance * 100, 2);
string percentGainText = percentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%"; string percentGainText = percentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%";
if (Model.PTData.TransactionData.Transactions.Count > 0) { if (Model.PTData.TransactionData.Transactions.Count > 0)
{
percentGainText = "<i class=\"fa fa-info-circle text-muted\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"You have added at least one manual transaction, so the total gain percentage cannot be calculated.\"></i>"; percentGainText = "<i class=\"fa fa-info-circle text-muted\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"You have added at least one manual transaction, so the total gain percentage cannot be calculated.\"></i>";
} }
@ -216,12 +206,10 @@
.donut(true) //Turn on Donut mode. Makes pie chart look tasty! .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. .donutRatio(0.3) //Configure how big you want the donut hole size to be.
; ;
d3.select("#AssetDistribution svg") d3.select("#AssetDistribution svg")
.datum(@Html.Raw(Model.AssetDistributionData)) .datum(@Html.Raw(Model.AssetDistributionData))
.transition().duration(350) .transition().duration(350)
.call(chart); .call(chart);
return chart; return chart;
}); });
</text> </text>
@ -239,7 +227,6 @@
$.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)".'); $.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> </text>
} }
@if (!Model.TrendChartDataJSON.Equals("")) { @if (!Model.TrendChartDataJSON.Equals("")) {
<text> <text>
nv.addGraph(function () { nv.addGraph(function () {
@ -255,7 +242,6 @@
}); });
</text> </text>
} }
@if (!Model.ProfitChartDataJSON.Equals("")) { @if (!Model.ProfitChartDataJSON.Equals("")) {
<text> <text>
nv.addGraph(function () { nv.addGraph(function () {
@ -267,7 +253,6 @@
lineChart.yAxis.axisLabel('Daily Profit').tickFormat(d3.format(',.2f')); lineChart.yAxis.axisLabel('Daily Profit').tickFormat(d3.format(',.2f'));
d3.select('.profit-chart svg').attr('perserveAspectRatio', 'xMinYMid').datum(chartData).transition().duration(500).call(lineChart); 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 //nv.utils.windowResize(lineChart.update); v1.3.0 => Removed this line to prevent memory leak
return lineChart; return lineChart;
}); });
</text> </text>

View File

@ -19,6 +19,9 @@ namespace Monitor.Pages {
public string AssetDistributionData = ""; public string AssetDistributionData = "";
public double currentBalance = 0; public double currentBalance = 0;
public string currentBalanceString = ""; public string currentBalanceString = "";
public double TotalBagCost = 0;
public double TotalBagValue = 0;
public double totalCurrentValue = 0;
public void OnGet() { public void OnGet() {
// Initialize Config // Initialize Config
base.Init(); base.Init();
@ -49,7 +52,6 @@ namespace Monitor.Pages {
BuildMarketTrendChartData(); BuildMarketTrendChartData();
BuildProfitChartData(); BuildProfitChartData();
} }
private void BuildMarketTrendChartData() { private void BuildMarketTrendChartData() {
if (MarketTrends.Count > 0) { if (MarketTrends.Count > 0) {
TrendChartDataJSON = "["; TrendChartDataJSON = "[";
@ -96,13 +98,10 @@ namespace Monitor.Pages {
MarketTrendChange mtc = latestTickRange.First(); MarketTrendChange mtc = latestTickRange.First();
if (trendChartTicks > 0) TrendChartDataJSON += ",\n"; if (trendChartTicks > 0) TrendChartDataJSON += ",\n";
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0; 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")) + "}"; 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")) + "}";
} }
TrendChartDataJSON += "]"; TrendChartDataJSON += "]";
TrendChartDataJSON += "}"; TrendChartDataJSON += "}";
mtIndex++; mtIndex++;
} }
} }
@ -140,13 +139,52 @@ namespace Monitor.Pages {
} }
private void BuildAssetDistributionData() private void BuildAssetDistributionData()
{ {
double PairsBalance = PTData.GetPairsBalance(); // the per PT-Eelroy, the PT API doesn't provide these values when using leverage, so they are calculated here to cover either case.
double DCABalance = PTData.GetDCABalance(); double PairsBalance = 0.0;
double PendingBalance = PTData.GetPendingBalance(); double DCABalance = 0.0;
double DustBalance = PTData.GetDustBalance(); double PendingBalance = 0.0;
double TotalValue = PTData.GetCurrentBalance(); double AvailableBalance = PTData.GetCurrentBalance();
double AvailableBalance = (TotalValue - PairsBalance - DCABalance - PendingBalance - DustBalance); bool isSellStrategyTrue =false;
bool isTrailingSellActive =false;
foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog)
{
Core.Main.DataObjects.PTMagicData.MarketPairSummary mps = null;
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
// Aggregate totals
if (dcaLogEntry.Leverage == 0)
{
if (sellStrategyText.Contains("PENDING"))
{
PendingBalance = PendingBalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice);
}
else if (dcaLogEntry.BuyStrategies.Count > 0)
{
DCABalance = DCABalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice);
}
else
{
PairsBalance = PairsBalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice);
}
}
else
{
if (sellStrategyText.Contains("PENDING"))
{
PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
}
else if (dcaLogEntry.BuyStrategies.Count > 0)
{
DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
}
else
{
PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
}
}
}
totalCurrentValue = PendingBalance + DCABalance + PairsBalance + AvailableBalance;
AssetDistributionData = "["; AssetDistributionData = "[";
AssetDistributionData += "{label: 'Pairs',color: '#82E0AA',value: '" + PairsBalance.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "'},"; AssetDistributionData += "{label: 'Pairs',color: '#82E0AA',value: '" + PairsBalance.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "'},";
AssetDistributionData += "{label: 'DCA',color: '#D98880',value: '" + DCABalance.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "'},"; AssetDistributionData += "{label: 'DCA',color: '#D98880',value: '" + DCABalance.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "'},";

View File

@ -93,12 +93,12 @@
<thead> <thead>
<tr> <tr>
<th>Market</th> <th>Market</th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Market trend last 24 hours">24H Trend</th> <th class="text-left" data-toggle="tooltip" data-placement="top" title="Market trend last 24 hours">24H</th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Total Buy Cost">Cost</th> <th class="text-left" data-toggle="tooltip" data-placement="top" title="Total Buy Cost">Cost</th>
<th></th> <th></th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Active buy strategies">DCA Buy Strats</th> <th class="text-left" data-toggle="tooltip" data-placement="top" title="Active buy strategies">DCA</th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Active sell strategies">Sell Strats</th> <th class="text-left" data-toggle="tooltip" data-placement="top" title="Active sell strategies">Sell</th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Target Profit for sale">Target Profit</th> <th class="text-left" data-toggle="tooltip" data-placement="top" title="Target profit to sell">Target</th>
<th class="text-left" data-toggle="tooltip" data-placement="top" title="Current Profit">Profit</th> <th class="text-left" data-toggle="tooltip" data-placement="top" title="Current Profit">Profit</th>
<th></th> <th></th>
</tr> </tr>
@ -137,11 +137,30 @@
} }
bool buyDisabled = false; bool buyDisabled = false;
string leverage = "";
double leverageValue = 0;
string buyStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.BuyStrategies, dcaLogEntry.BuyStrategy, isBuyStrategyTrue, isTrailingBuyActive); string buyStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.BuyStrategies, dcaLogEntry.BuyStrategy, isBuyStrategyTrue, isTrailingBuyActive);
if (!Core.ProfitTrailer.StrategyHelper.IsValidStrategy(buyStrategyText, true)) {
if (!Core.ProfitTrailer.StrategyHelper.IsValidStrategy(buyStrategyText, true))
{
buyDisabled = true; buyDisabled = true;
} }
// if leverage, recalculate profit target
if (buyStrategyText.Contains("CROSSED"))
{
string leverageText = buyStrategyText.Remove(0, buyStrategyText.IndexOf("CROSSED")+9);
leverage = leverageText.Remove(leverageText.IndexOf(".0)"), leverageText.Length - leverageText.IndexOf(".0)"));
leverageValue = double.Parse(leverage);
}
if (buyStrategyText.Contains("ISOLATED"))
{
string leverageText = buyStrategyText.Remove(0, buyStrategyText.IndexOf("ISOLATED")+10);
leverage = leverageText.Remove(leverageText.IndexOf(".0)"), leverageText.Length - leverageText.IndexOf(".0)"));
leverageValue = double.Parse(leverage);
}
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive); string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Model.Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
// Check for when PT loses the value of a pair // Check for when PT loses the value of a pair
@ -197,12 +216,19 @@
<span data-toggle="tooltip" data-placement="top" title="DCA is disabled"><i class="fa fa-ban text-highlight"></i></span> <span data-toggle="tooltip" data-placement="top" title="DCA is disabled"><i class="fa fa-ban text-highlight"></i></span>
} }
</td> </td>
<td>@Html.Raw(buyStrategyText)</td> <td>@Html.Raw(buyStrategyText)</td>
<td>@Html.Raw(sellStrategyText)</td> <td>@Html.Raw(sellStrategyText)</td>
@if (leverageValue == 0)
{
<td class="@Html.Raw((dcaLogEntry.TargetGainValue.HasValue && (dcaLogEntry.ProfitPercent > dcaLogEntry.TargetGainValue.Value)) ? "text-success" : "text-danger")">@Html.Raw(dcaLogEntry.TargetGainValue.HasValue ? dcaLogEntry.TargetGainValue.Value.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%" : "&nbsp")</td> <td class="@Html.Raw((dcaLogEntry.TargetGainValue.HasValue && (dcaLogEntry.ProfitPercent > dcaLogEntry.TargetGainValue.Value)) ? "text-success" : "text-danger")">@Html.Raw(dcaLogEntry.TargetGainValue.HasValue ? dcaLogEntry.TargetGainValue.Value.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%" : "&nbsp")</td>
}
else
{
double leverageTargetGain = leverageValue * dcaLogEntry.TargetGainValue.Value;
<td class="@Html.Raw((dcaLogEntry.TargetGainValue.HasValue && (dcaLogEntry.ProfitPercent > dcaLogEntry.TargetGainValue.Value)) ? "text-success" : "text-danger")">@Html.Raw(dcaLogEntry.TargetGainValue.HasValue ? leverageTargetGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%" : "&nbsp")</td>
}
@if(!@lostValue) @if(!@lostValue)
{ {
@ -224,7 +250,8 @@
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td class="text-autocolor">@Html.Raw((((Model.TotalBagValue - Model.TotalBagCost) / Model.TotalBagCost) * 100).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))%</td>
<td class="text-autocolor">@Html.Raw( (((Model.TotalBagValue - Model.TotalBagCost) / Model.TotalBagCost) * 100).ToString("#0.00", new System.Globalization.CultureInfo("en-US")))%</td>
</tbody> </tbody>
</table> </table>