2018-05-22 10:11:50 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
using System.Linq;
|
2019-01-07 15:33:02 +01:00
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Http;
|
2019-02-26 00:17:10 +01:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Newtonsoft.Json;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
using Newtonsoft.Json.Linq;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
using Core.Main.DataObjects.PTMagicData;
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
namespace Core.Main.DataObjects
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public class ProfitTrailerData
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
private SummaryData _summary = null;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
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 DateTimeOffset _dateTimeNow = Constants.confMinDate;
|
2019-02-26 00:17:10 +01:00
|
|
|
|
|
2019-01-07 15:33:02 +01:00
|
|
|
|
public ProfitTrailerData(PTMagicConfiguration systemConfiguration)
|
2018-12-31 04:26:45 +01:00
|
|
|
|
{
|
2019-01-13 13:43:47 +01:00
|
|
|
|
_systemConfiguration = systemConfiguration;
|
|
|
|
|
|
2019-01-07 15:33:02 +01:00
|
|
|
|
string html = "";
|
|
|
|
|
string url = systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL + "api/data?token=" + systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
2019-02-26 00:17:10 +01:00
|
|
|
|
// Get the data from PT
|
|
|
|
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
|
|
|
|
request.AutomaticDecompression = DecompressionMethods.GZip;
|
|
|
|
|
request.KeepAlive = true;
|
2018-08-11 01:14:22 +02:00
|
|
|
|
|
2019-02-26 00:17:10 +01:00
|
|
|
|
WebResponse response = request.GetResponse();
|
|
|
|
|
Stream dataStream = response.GetResponseStream();
|
|
|
|
|
StreamReader reader = new StreamReader(dataStream);
|
|
|
|
|
html = reader.ReadToEnd();
|
|
|
|
|
reader.Close();
|
|
|
|
|
response.Close();
|
2018-12-15 22:07:29 +01:00
|
|
|
|
|
2019-02-26 00:17:10 +01:00
|
|
|
|
// Parse the JSON and build the data sets
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dynamic rawPTData = JObject.Parse(html);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
2019-02-26 00:17:10 +01:00
|
|
|
|
Parallel.Invoke(() =>
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
_summary = BuildSummaryData(rawPTData);
|
|
|
|
|
},
|
|
|
|
|
() =>
|
|
|
|
|
{
|
|
|
|
|
if (rawPTData.sellLogData != null)
|
2019-02-26 00:17:10 +01:00
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
this.BuildSellLogData(rawPTData.sellLogData, _systemConfiguration);
|
2019-02-26 00:17:10 +01:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
() =>
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-02-26 00:17:10 +01:00
|
|
|
|
if (rawPTData.bbBuyLogData != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
this.BuildBuyLogData(rawPTData.bbBuyLogData);
|
2019-02-26 00:17:10 +01:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
() =>
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
if (rawPTData.dcaLogData != null)
|
2019-02-26 00:17:10 +01:00
|
|
|
|
{
|
2019-05-04 13:57:49 +02:00
|
|
|
|
this.BuildDCALogData(rawPTData.dcaLogData, rawPTData.gainLogData, rawPTData.pendingLogData, _systemConfiguration);
|
2019-02-26 00:17:10 +01:00
|
|
|
|
}
|
|
|
|
|
});
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
// Convert local offset time to UTC
|
|
|
|
|
TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
|
|
|
|
_dateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 01:01:43 +01:00
|
|
|
|
public SummaryData Summary
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _summary;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public List<SellLogData> SellLog
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
return _sellLog;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public List<SellLogData> SellLogToday
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
return _sellLog.FindAll(sl => sl.SoldDate.Date == _dateTimeNow.DateTime.Date);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public List<SellLogData> SellLogYesterday
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
return _sellLog.FindAll(sl => sl.SoldDate.Date == _dateTimeNow.DateTime.AddDays(-1).Date);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public List<SellLogData> SellLogLast7Days
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
return _sellLog.FindAll(sl => sl.SoldDate.Date >= _dateTimeNow.DateTime.AddDays(-7).Date);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-14 04:09:58 +01:00
|
|
|
|
public List<SellLogData> SellLogLast30Days
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _sellLog.FindAll(sl => sl.SoldDate.Date >= _dateTimeNow.DateTime.AddDays(-30).Date);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public List<DCALogData> DCALog
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
return _dcaLog;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public List<BuyLogData> BuyLog
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
return _buyLog;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public TransactionData TransactionData
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
if (_transactionData == null) _transactionData = new TransactionData(_ptmBasePath);
|
|
|
|
|
return _transactionData;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public double GetCurrentBalance()
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
return
|
|
|
|
|
(this.Summary.Balance +
|
|
|
|
|
this.Summary.PairsValue +
|
|
|
|
|
this.Summary.DCAValue +
|
|
|
|
|
this.Summary.PendingValue +
|
|
|
|
|
this.Summary.DustValue);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
}
|
2019-04-30 17:36:27 +02:00
|
|
|
|
public double GetPairsBalance()
|
|
|
|
|
{
|
|
|
|
|
return
|
|
|
|
|
(this.Summary.PairsValue);
|
|
|
|
|
}
|
|
|
|
|
public double GetDCABalance()
|
|
|
|
|
{
|
|
|
|
|
return
|
|
|
|
|
(this.Summary.DCAValue);
|
|
|
|
|
}
|
|
|
|
|
public double GetPendingBalance()
|
|
|
|
|
{
|
|
|
|
|
return
|
|
|
|
|
(this.Summary.PendingValue);
|
|
|
|
|
}
|
|
|
|
|
public double GetDustBalance()
|
|
|
|
|
{
|
|
|
|
|
return
|
|
|
|
|
(this.Summary.DustValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
public double GetSnapshotBalance(DateTime snapshotDateTime)
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
double result = _systemConfiguration.GeneralSettings.Application.StartBalance;
|
|
|
|
|
|
|
|
|
|
result += this.SellLog.FindAll(sl => sl.SoldDate.Date < snapshotDateTime.Date).Sum(sl => sl.Profit);
|
2019-03-26 01:01:43 +01:00
|
|
|
|
result += this.TransactionData.Transactions.FindAll(t => t.UTCDateTime < snapshotDateTime).Sum(t => t.Amount);
|
|
|
|
|
|
|
|
|
|
// Calculate holdings for snapshot date
|
|
|
|
|
result += this.DCALog.FindAll(pairs => pairs.FirstBoughtDate <= snapshotDateTime).Sum(pairs => pairs.CurrentValue);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 01:01:43 +01:00
|
|
|
|
private SummaryData BuildSummaryData(dynamic PTData)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
return new SummaryData()
|
|
|
|
|
{
|
|
|
|
|
Market = PTData.market,
|
|
|
|
|
Balance = PTData.realBalance,
|
|
|
|
|
PairsValue = PTData.totalPairsCurrentValue,
|
|
|
|
|
DCAValue = PTData.totalDCACurrentValue,
|
|
|
|
|
PendingValue = PTData.totalPendingCurrentValue,
|
|
|
|
|
DustValue = PTData.totalDustCurrentValue
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BuildSellLogData(dynamic rawSellLogData, PTMagicConfiguration systemConfiguration)
|
|
|
|
|
{
|
|
|
|
|
foreach (var rsld in rawSellLogData)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
SellLogData sellLogData = new SellLogData();
|
|
|
|
|
sellLogData.SoldAmount = rsld.soldAmount;
|
|
|
|
|
sellLogData.BoughtTimes = rsld.boughtTimes;
|
|
|
|
|
sellLogData.Market = rsld.market;
|
|
|
|
|
sellLogData.ProfitPercent = rsld.profit;
|
|
|
|
|
sellLogData.SoldPrice = rsld.currentPrice;
|
2019-01-15 13:43:07 +01:00
|
|
|
|
sellLogData.AverageBuyPrice = rsld.avgPrice;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
sellLogData.TotalCost = sellLogData.SoldAmount * sellLogData.AverageBuyPrice;
|
|
|
|
|
|
|
|
|
|
double soldValueRaw = (sellLogData.SoldAmount * sellLogData.SoldPrice);
|
2019-03-26 01:01:43 +01:00
|
|
|
|
double soldValueAfterFees = soldValueRaw - (soldValueRaw * ((double)rsld.fee / 100));
|
2018-05-22 10:11:50 +02:00
|
|
|
|
sellLogData.SoldValue = soldValueAfterFees;
|
2019-02-26 00:17:10 +01:00
|
|
|
|
sellLogData.Profit = Math.Round(sellLogData.SoldValue - sellLogData.TotalCost, 8);
|
2019-01-07 15:33:02 +01:00
|
|
|
|
|
|
|
|
|
//Convert Unix Timestamp to Datetime
|
2019-02-26 00:17:10 +01:00
|
|
|
|
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dtDateTime = dtDateTime.AddSeconds((double)rsld.soldDate).ToUniversalTime();
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
// Profit Trailer sales are saved in UTC
|
2019-01-07 15:33:02 +01:00
|
|
|
|
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);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
// Convert UTC sales time to local offset time
|
2018-12-31 04:26:45 +01:00
|
|
|
|
TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
|
|
|
|
ptSoldDate = ptSoldDate.ToOffset(offsetTimeSpan);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
sellLogData.SoldDate = ptSoldDate.DateTime;
|
|
|
|
|
|
|
|
|
|
_sellLog.Add(sellLogData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-04 13:57:49 +02:00
|
|
|
|
private void BuildDCALogData(dynamic rawDCALogData, dynamic rawPairsLogData, dynamic rawPendingLogData, PTMagicConfiguration systemConfiguration)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var rdld in rawDCALogData)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
DCALogData dcaLogData = new DCALogData();
|
2019-01-15 13:43:07 +01:00
|
|
|
|
dcaLogData.Amount = rdld.totalAmount;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.BoughtTimes = rdld.boughtTimes;
|
|
|
|
|
dcaLogData.Market = rdld.market;
|
|
|
|
|
dcaLogData.ProfitPercent = rdld.profit;
|
2019-01-15 13:43:07 +01:00
|
|
|
|
dcaLogData.AverageBuyPrice = rdld.avgPrice;
|
|
|
|
|
dcaLogData.TotalCost = rdld.totalCost;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.BuyTriggerPercent = rdld.buyProfit;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dcaLogData.CurrentLowBBValue = rdld.bbLow == null ? 0 : rdld.bbLow;
|
|
|
|
|
dcaLogData.CurrentHighBBValue = rdld.highBb == null ? 0 : rdld.highBb;
|
|
|
|
|
dcaLogData.BBTrigger = rdld.bbTrigger == null ? 0 : rdld.bbTrigger;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.CurrentPrice = rdld.currentPrice;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dcaLogData.SellTrigger = rdld.triggerValue == null ? 0 : rdld.triggerValue;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.PercChange = rdld.percChange;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dcaLogData.BuyStrategy = rdld.buyStrategy == null ? "" : rdld.buyStrategy;
|
|
|
|
|
dcaLogData.SellStrategy = rdld.sellStrategy == null ? "" : rdld.sellStrategy;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
if (rdld.positive != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dcaLogData.IsTrailing = ((string)rdld.positive).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
dcaLogData.IsTrue = ((string)rdld.positive).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
2018-12-15 22:07:29 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (rdld.buyStrategies != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var bs in rdld.buyStrategies)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
Strategy buyStrategy = new Strategy();
|
|
|
|
|
buyStrategy.Type = bs.type;
|
|
|
|
|
buyStrategy.Name = bs.name;
|
|
|
|
|
buyStrategy.EntryValue = bs.entryValue;
|
|
|
|
|
buyStrategy.EntryValueLimit = bs.entryValueLimit;
|
|
|
|
|
buyStrategy.TriggerValue = bs.triggerValue;
|
|
|
|
|
buyStrategy.CurrentValue = bs.currentValue;
|
|
|
|
|
buyStrategy.CurrentValuePercentage = bs.currentValuePercentage;
|
|
|
|
|
buyStrategy.Decimals = bs.decimals;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
buyStrategy.IsTrailing = ((string)bs.positive).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
buyStrategy.IsTrue = ((string)bs.positive).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
dcaLogData.BuyStrategies.Add(buyStrategy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
if (rdld.sellStrategies != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var ss in rdld.sellStrategies)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
Strategy sellStrategy = new Strategy();
|
|
|
|
|
sellStrategy.Type = ss.type;
|
|
|
|
|
sellStrategy.Name = ss.name;
|
|
|
|
|
sellStrategy.EntryValue = ss.entryValue;
|
|
|
|
|
sellStrategy.EntryValueLimit = ss.entryValueLimit;
|
|
|
|
|
sellStrategy.TriggerValue = ss.triggerValue;
|
|
|
|
|
sellStrategy.CurrentValue = ss.currentValue;
|
|
|
|
|
sellStrategy.CurrentValuePercentage = ss.currentValuePercentage;
|
|
|
|
|
sellStrategy.Decimals = ss.decimals;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
sellStrategy.IsTrailing = ((string)ss.positive).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
sellStrategy.IsTrue = ((string)ss.positive).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
dcaLogData.SellStrategies.Add(sellStrategy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 01:01:43 +01:00
|
|
|
|
// Calculate current value
|
|
|
|
|
dcaLogData.CurrentValue = dcaLogData.CurrentPrice * dcaLogData.Amount;
|
|
|
|
|
|
2019-01-07 15:33:02 +01:00
|
|
|
|
//Convert Unix Timestamp to Datetime
|
2019-02-26 00:17:10 +01:00
|
|
|
|
System.DateTime rdldDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
|
2019-03-26 01:01:43 +01:00
|
|
|
|
rdldDateTime = rdldDateTime.AddSeconds((double)rdld.firstBoughtDate).ToUniversalTime();
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
// Profit Trailer bought times are saved in UTC
|
2019-01-07 19:00:40 +01:00
|
|
|
|
if (rdld.firstBoughtDate > 0)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-01-07 15:33:02 +01:00
|
|
|
|
DateTimeOffset ptFirstBoughtDate = DateTimeOffset.Parse(rdldDateTime.Year.ToString() + "-" + rdldDateTime.Month.ToString("00") + "-" + rdldDateTime.Day.ToString("00") + "T" + rdldDateTime.Hour.ToString("00") + ":" + rdldDateTime.Minute.ToString("00") + ":" + rdldDateTime.Second.ToString("00"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
// Convert UTC bought time to local offset time
|
|
|
|
|
TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
|
|
|
|
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(offsetTimeSpan);
|
|
|
|
|
|
|
|
|
|
dcaLogData.FirstBoughtDate = ptFirstBoughtDate.DateTime;
|
2018-12-15 22:07:29 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.FirstBoughtDate = Constants.confMinDate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dcaLog.Add(dcaLogData);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var rpld in rawPairsLogData)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
DCALogData dcaLogData = new DCALogData();
|
2019-01-15 13:43:07 +01:00
|
|
|
|
dcaLogData.Amount = rpld.totalAmount;
|
2019-05-04 13:57:49 +02:00
|
|
|
|
dcaLogData.BoughtTimes = 0;
|
|
|
|
|
dcaLogData.Market = rpld.market;
|
|
|
|
|
dcaLogData.ProfitPercent = rpld.profit;
|
|
|
|
|
dcaLogData.AverageBuyPrice = rpld.avgPrice;
|
|
|
|
|
dcaLogData.TotalCost = rpld.totalCost;
|
|
|
|
|
dcaLogData.BuyTriggerPercent = rpld.buyProfit;
|
|
|
|
|
dcaLogData.CurrentPrice = rpld.currentPrice;
|
|
|
|
|
dcaLogData.SellTrigger = rpld.triggerValue == null ? 0 : rpld.triggerValue;
|
|
|
|
|
dcaLogData.PercChange = rpld.percChange;
|
|
|
|
|
dcaLogData.BuyStrategy = rpld.buyStrategy == null ? "" : rpld.buyStrategy;
|
|
|
|
|
dcaLogData.SellStrategy = rpld.sellStrategy == null ? "" : rpld.sellStrategy;
|
|
|
|
|
dcaLogData.IsTrailing = false;
|
|
|
|
|
|
|
|
|
|
if (rpld.sellStrategies != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var ss in rpld.sellStrategies)
|
|
|
|
|
{
|
|
|
|
|
Strategy sellStrategy = new Strategy();
|
|
|
|
|
sellStrategy.Type = ss.type;
|
|
|
|
|
sellStrategy.Name = ss.name;
|
|
|
|
|
sellStrategy.EntryValue = ss.entryValue;
|
|
|
|
|
sellStrategy.EntryValueLimit = ss.entryValueLimit;
|
|
|
|
|
sellStrategy.TriggerValue = ss.triggerValue;
|
|
|
|
|
sellStrategy.CurrentValue = ss.currentValue;
|
|
|
|
|
sellStrategy.CurrentValuePercentage = ss.currentValuePercentage;
|
|
|
|
|
sellStrategy.Decimals = ss.decimals;
|
|
|
|
|
sellStrategy.IsTrailing = ((string)ss.positive).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
sellStrategy.IsTrue = ((string)ss.positive).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
|
|
|
|
|
dcaLogData.SellStrategies.Add(sellStrategy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Convert Unix Timestamp to Datetime
|
|
|
|
|
System.DateTime rpldDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
|
|
|
|
|
rpldDateTime = rpldDateTime.AddSeconds((double)rpld.firstBoughtDate).ToUniversalTime();
|
|
|
|
|
|
|
|
|
|
// Profit Trailer bought times are saved in UTC
|
|
|
|
|
if (rpld.firstBoughtDate > 0)
|
|
|
|
|
{
|
|
|
|
|
DateTimeOffset ptFirstBoughtDate = DateTimeOffset.Parse(rpldDateTime.Year.ToString() + "-" + rpldDateTime.Month.ToString("00") + "-" + rpldDateTime.Day.ToString("00") + "T" + rpldDateTime.Hour.ToString("00") + ":" + rpldDateTime.Minute.ToString("00") + ":" + rpldDateTime.Second.ToString("00"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
|
|
|
|
|
|
|
|
|
// Convert UTC bought time to local offset time
|
|
|
|
|
TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
|
|
|
|
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(offsetTimeSpan);
|
|
|
|
|
|
|
|
|
|
dcaLogData.FirstBoughtDate = ptFirstBoughtDate.DateTime;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dcaLogData.FirstBoughtDate = Constants.confMinDate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dcaLog.Add(dcaLogData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var rpld in rawPendingLogData)
|
|
|
|
|
{
|
|
|
|
|
DCALogData dcaLogData = new DCALogData();
|
|
|
|
|
dcaLogData.Amount = rpld.totalAmount;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.BoughtTimes = 0;
|
|
|
|
|
dcaLogData.Market = rpld.market;
|
|
|
|
|
dcaLogData.ProfitPercent = rpld.profit;
|
2019-01-15 13:43:07 +01:00
|
|
|
|
dcaLogData.AverageBuyPrice = rpld.avgPrice;
|
|
|
|
|
dcaLogData.TotalCost = rpld.totalCost;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.BuyTriggerPercent = rpld.buyProfit;
|
|
|
|
|
dcaLogData.CurrentPrice = rpld.currentPrice;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dcaLogData.SellTrigger = rpld.triggerValue == null ? 0 : rpld.triggerValue;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.PercChange = rpld.percChange;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
dcaLogData.BuyStrategy = rpld.buyStrategy == null ? "" : rpld.buyStrategy;
|
|
|
|
|
dcaLogData.SellStrategy = rpld.sellStrategy == null ? "" : rpld.sellStrategy;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.IsTrailing = false;
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
if (rpld.sellStrategies != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var ss in rpld.sellStrategies)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
Strategy sellStrategy = new Strategy();
|
|
|
|
|
sellStrategy.Type = ss.type;
|
|
|
|
|
sellStrategy.Name = ss.name;
|
|
|
|
|
sellStrategy.EntryValue = ss.entryValue;
|
|
|
|
|
sellStrategy.EntryValueLimit = ss.entryValueLimit;
|
|
|
|
|
sellStrategy.TriggerValue = ss.triggerValue;
|
|
|
|
|
sellStrategy.CurrentValue = ss.currentValue;
|
|
|
|
|
sellStrategy.CurrentValuePercentage = ss.currentValuePercentage;
|
|
|
|
|
sellStrategy.Decimals = ss.decimals;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
sellStrategy.IsTrailing = ((string)ss.positive).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
sellStrategy.IsTrue = ((string)ss.positive).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
dcaLogData.SellStrategies.Add(sellStrategy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 15:33:02 +01:00
|
|
|
|
//Convert Unix Timestamp to Datetime
|
2019-02-26 00:17:10 +01:00
|
|
|
|
System.DateTime rpldDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
|
2019-03-26 01:01:43 +01:00
|
|
|
|
rpldDateTime = rpldDateTime.AddSeconds((double)rpld.firstBoughtDate).ToUniversalTime();
|
2019-01-07 15:33:02 +01:00
|
|
|
|
|
2018-05-22 10:11:50 +02:00
|
|
|
|
// Profit Trailer bought times are saved in UTC
|
2019-01-07 19:00:40 +01:00
|
|
|
|
if (rpld.firstBoughtDate > 0)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-01-07 15:33:02 +01:00
|
|
|
|
DateTimeOffset ptFirstBoughtDate = DateTimeOffset.Parse(rpldDateTime.Year.ToString() + "-" + rpldDateTime.Month.ToString("00") + "-" + rpldDateTime.Day.ToString("00") + "T" + rpldDateTime.Hour.ToString("00") + ":" + rpldDateTime.Minute.ToString("00") + ":" + rpldDateTime.Second.ToString("00"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
|
|
|
|
// Convert UTC bought time to local offset time
|
|
|
|
|
TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
|
|
|
|
|
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(offsetTimeSpan);
|
|
|
|
|
|
|
|
|
|
dcaLogData.FirstBoughtDate = ptFirstBoughtDate.DateTime;
|
2018-12-15 22:07:29 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
dcaLogData.FirstBoughtDate = Constants.confMinDate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dcaLog.Add(dcaLogData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 01:01:43 +01:00
|
|
|
|
private void BuildBuyLogData(dynamic rawBuyLogData)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var rbld in rawBuyLogData)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
BuyLogData buyLogData = new BuyLogData() { IsTrailing = false, IsTrue = false, IsSom = false, TrueStrategyCount = 0 };
|
2018-05-22 10:11:50 +02:00
|
|
|
|
buyLogData.Market = rbld.market;
|
|
|
|
|
buyLogData.ProfitPercent = rbld.profit;
|
|
|
|
|
buyLogData.CurrentPrice = rbld.currentPrice;
|
|
|
|
|
buyLogData.PercChange = rbld.percChange;
|
|
|
|
|
|
2018-12-15 22:07:29 +01:00
|
|
|
|
if (rbld.positive != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
buyLogData.IsTrailing = ((string)(rbld.positive)).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
buyLogData.IsTrue = ((string)(rbld.positive)).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
2018-12-15 22:07:29 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (rbld.buyStrategies != null)
|
|
|
|
|
{
|
2019-03-26 01:01:43 +01:00
|
|
|
|
foreach (var bs in rbld.buyStrategies)
|
2018-12-15 22:07:29 +01:00
|
|
|
|
{
|
2018-05-22 10:11:50 +02:00
|
|
|
|
Strategy buyStrategy = new Strategy();
|
|
|
|
|
buyStrategy.Type = bs.type;
|
|
|
|
|
buyStrategy.Name = bs.name;
|
|
|
|
|
buyStrategy.EntryValue = bs.entryValue;
|
|
|
|
|
buyStrategy.EntryValueLimit = bs.entryValueLimit;
|
|
|
|
|
buyStrategy.TriggerValue = bs.triggerValue;
|
|
|
|
|
buyStrategy.CurrentValue = bs.currentValue;
|
|
|
|
|
buyStrategy.CurrentValuePercentage = bs.currentValuePercentage;
|
|
|
|
|
buyStrategy.Decimals = bs.decimals;
|
2019-03-26 01:01:43 +01:00
|
|
|
|
buyStrategy.IsTrailing = ((string)(bs.positive)).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
|
|
|
|
|
buyStrategy.IsTrue = ((string)(bs.positive)).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
|
2018-05-22 10:11:50 +02:00
|
|
|
|
|
2019-03-19 00:32:10 +01:00
|
|
|
|
// Is SOM?
|
|
|
|
|
buyLogData.IsSom = buyLogData.IsSom || buyStrategy.Name.Equals("som enabled", StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
// Is the pair trailing?
|
|
|
|
|
buyLogData.IsTrailing = buyLogData.IsTrailing || buyStrategy.IsTrailing;
|
|
|
|
|
buyLogData.IsTrue = buyLogData.IsTrue || buyStrategy.IsTrue;
|
|
|
|
|
|
|
|
|
|
// True status strategy count total
|
|
|
|
|
buyLogData.TrueStrategyCount += buyStrategy.IsTrue ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
// Add
|
2018-05-22 10:11:50 +02:00
|
|
|
|
buyLogData.BuyStrategies.Add(buyStrategy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_buyLog.Add(buyLogData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|