PTMagic/Core/DataObjects/ProfitTrailerData.cs

666 lines
26 KiB
C#
Raw Normal View History

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.Threading.Tasks;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
2018-05-22 10:11:50 +02:00
using Core.Main.DataObjects.PTMagicData;
namespace Core.Main.DataObjects
{
2018-05-22 10:11:50 +02:00
public class ProfitTrailerData
{
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 DateTime _buyLogRefresh = DateTime.UtcNow, _sellLogRefresh = DateTime.UtcNow, _dcaLogRefresh = DateTime.UtcNow, _summaryRefresh = DateTime.UtcNow;
private volatile object _buyLock = new object(), _sellLock = new object(), _dcaLock = new object(), _summaryLock = new object();
2019-10-19 12:14:40 +02:00
private TimeSpan? _offsetTimeSpan = null;
2019-10-19 12:14:40 +02:00
// Constructor
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-10-19 12:14:40 +02:00
}
// Get a time span for the UTC offset from the settings
private TimeSpan OffsetTimeSpan
{
get
{
if (!_offsetTimeSpan.HasValue)
{
// Get offset for settings.
_offsetTimeSpan = TimeSpan.Parse(_systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
}
2019-01-13 13:43:47 +01:00
2019-10-19 12:14:40 +02:00
return _offsetTimeSpan.Value;
}
}
// Get the time with the settings UTC offset applied
private DateTimeOffset LocalizedTime
{
get
{
return DateTimeOffset.UtcNow.ToOffset(OffsetTimeSpan);
}
2018-05-22 10:11:50 +02:00
}
public SummaryData Summary
{
get
{
if (_summary == null || (DateTime.UtcNow > _summaryRefresh))
{
lock (_summaryLock)
{
// Thread double locking
if (_summary == null || (DateTime.UtcNow > _summaryRefresh))
{
_summary = BuildSummaryData(GetDataFromProfitTrailer("api/v2/data/misc"));
_summaryRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
}
return _summary;
}
}
public List<SellLogData> SellLog
{
get
{
if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh))
{
lock (_sellLock)
{
// Thread double locking
if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh))
{
_sellLog.Clear();
this.BuildSellLogData(GetDataFromProfitTrailer("/api/v2/data/sales"));
_sellLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
}
2018-05-22 10:11:50 +02:00
return _sellLog;
}
}
public List<SellLogData> SellLogToday
{
get
{
2019-10-19 12:14:40 +02:00
return SellLog.FindAll(sl => sl.SoldDate.Date == LocalizedTime.DateTime.Date);
2018-05-22 10:11:50 +02:00
}
}
public List<SellLogData> SellLogYesterday
{
get
{
2019-10-19 12:14:40 +02:00
return SellLog.FindAll(sl => sl.SoldDate.Date == LocalizedTime.DateTime.AddDays(-1).Date);
2018-05-22 10:11:50 +02:00
}
}
public List<SellLogData> SellLogLast7Days
{
get
{
2019-10-19 12:14:40 +02:00
return SellLog.FindAll(sl => sl.SoldDate.Date >= LocalizedTime.DateTime.AddDays(-7).Date);
2018-05-22 10:11:50 +02:00
}
}
2019-01-14 04:09:58 +01:00
public List<SellLogData> SellLogLast30Days
{
get
{
2019-10-19 12:14:40 +02:00
return SellLog.FindAll(sl => sl.SoldDate.Date >= LocalizedTime.DateTime.AddDays(-30).Date);
2019-01-14 04:09:58 +01:00
}
}
public List<DCALogData> DCALog
{
get
{
if (_dcaLog == null || (DateTime.UtcNow > _dcaLogRefresh))
{
lock (_dcaLock)
{
// Thread double locking
if (_dcaLog == null || (DateTime.UtcNow > _dcaLogRefresh))
{
dynamic dcaData = null, pairsData = null, pendingData = null, watchData = null;
_dcaLog.Clear();
Parallel.Invoke(() =>
{
dcaData = GetDataFromProfitTrailer("/api/v2/data/dca", true);
},
() =>
{
pairsData = GetDataFromProfitTrailer("/api/v2/data/pairs", true);
},
() =>
{
pendingData = GetDataFromProfitTrailer("/api/v2/data/pending", true);
},
() =>
{
watchData = GetDataFromProfitTrailer("/api/v2/data/watchmode", true);
});
this.BuildDCALogData(dcaData, pairsData, pendingData, watchData);
_dcaLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds - 1);
}
}
}
2018-05-22 10:11:50 +02:00
return _dcaLog;
}
}
public List<BuyLogData> BuyLog
{
get
{
if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh))
{
lock (_buyLock)
{
// Thread double locking
if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh))
{
_buyLog.Clear();
this.BuildBuyLogData(GetDataFromProfitTrailer("/api/v2/data/pbl", true));
_buyLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds - 1);
}
}
}
2018-05-22 10:11:50 +02:00
return _buyLog;
}
}
public TransactionData TransactionData
{
get
{
2018-05-22 10:11:50 +02:00
if (_transactionData == null) _transactionData = new TransactionData(_ptmBasePath);
return _transactionData;
}
}
public double GetCurrentBalance()
{
return
(this.Summary.Balance +
this.Summary.PairsValue +
this.Summary.DCAValue +
this.Summary.PendingValue +
this.Summary.DustValue);
2018-05-22 10:11:50 +02:00
}
public double GetPairsBalance()
2019-04-30 17:36:27 +02:00
{
return
2019-04-30 17:36:27 +02:00
(this.Summary.PairsValue);
}
public double GetDCABalance()
2019-04-30 17:36:27 +02:00
{
return
2019-04-30 17:36:27 +02:00
(this.Summary.DCAValue);
}
public double GetPendingBalance()
2019-04-30 17:36:27 +02:00
{
return
2019-04-30 17:36:27 +02:00
(this.Summary.PendingValue);
}
public double GetDustBalance()
{
return
2019-04-30 17:36:27 +02:00
(this.Summary.DustValue);
}
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);
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-10-13 19:19:26 +02:00
private dynamic GetDataFromProfitTrailer(string callPath, bool arrayReturned = false)
{
string rawBody = "";
string url = string.Format("{0}{1}?token={2}", _systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL, callPath, _systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken);
// Get the data from PT
Debug.WriteLine(String.Format("{0} - Calling '{1}'", DateTime.UtcNow, url));
2019-10-13 19:19:26 +02:00
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
request.KeepAlive = true;
WebResponse response = request.GetResponse();
using (Stream dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
rawBody = reader.ReadToEnd();
reader.Close();
}
response.Close();
// Parse the JSON and build the data sets
if (!arrayReturned)
{
return JObject.Parse(rawBody);
}
else
{
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
};
}
2019-10-13 19:19:26 +02:00
private void BuildSellLogData(dynamic rawSellLogData)
{
2019-10-13 19:19:26 +02:00
foreach (var rsld in rawSellLogData.data)
{
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;
2020-01-16 12:50:42 +01:00
if (sellLogData.ProfitPercent >0)
{
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 soldValueAfterFees = soldValueRaw - (soldValueRaw * ((double)rsld.fee / 100));
sellLogData.SoldValue = soldValueAfterFees;
sellLogData.Profit = Math.Round(sellLogData.SoldValue - sellLogData.TotalCost, 8);
}
2019-01-07 15:33:02 +01:00
//Convert Unix Timestamp to Datetime
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
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
2019-10-19 12:14:40 +02:00
ptSoldDate = ptSoldDate.ToOffset(OffsetTimeSpan);
2018-05-22 10:11:50 +02:00
sellLogData.SoldDate = ptSoldDate.DateTime;
_sellLog.Add(sellLogData);
}
}
2019-10-13 19:19:26 +02:00
private void BuildDCALogData(dynamic rawDCALogData, dynamic rawPairsLogData, dynamic rawPendingLogData, dynamic rawWatchModeLogData)
{
foreach (var rdld in rawDCALogData)
{
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;
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;
dcaLogData.SellTrigger = rdld.triggerValue == null ? 0 : rdld.triggerValue;
2018-05-22 10:11:50 +02:00
dcaLogData.PercChange = rdld.percChange;
dcaLogData.BuyStrategy = rdld.buyStrategy == null ? "" : rdld.buyStrategy;
dcaLogData.SellStrategy = rdld.sellStrategy == null ? "" : rdld.sellStrategy;
2018-05-22 10:11:50 +02:00
if (rdld.positive != null)
{
dcaLogData.IsTrailing = ((string)rdld.positive).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
dcaLogData.IsTrue = ((string)rdld.positive).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
}
else
{
if (rdld.buyStrategies != null)
{
foreach (var bs in rdld.buyStrategies)
{
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;
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);
}
}
if (rdld.sellStrategies != null)
{
foreach (var ss in rdld.sellStrategies)
{
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;
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);
}
}
}
// Calculate current value
dcaLogData.CurrentValue = dcaLogData.CurrentPrice * dcaLogData.Amount;
2019-01-07 15:33:02 +01:00
//Convert Unix Timestamp to Datetime
System.DateTime rdldDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
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)
{
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
2019-10-19 12:14:40 +02:00
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(OffsetTimeSpan);
2018-05-22 10:11:50 +02:00
dcaLogData.FirstBoughtDate = ptFirstBoughtDate.DateTime;
}
else
{
2018-05-22 10:11:50 +02:00
dcaLogData.FirstBoughtDate = Constants.confMinDate;
}
_dcaLog.Add(dcaLogData);
}
foreach (var rpld in rawPairsLogData)
{
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
2019-10-19 12:14:40 +02:00
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(OffsetTimeSpan);
2019-05-04 13:57:49 +02:00
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;
dcaLogData.SellTrigger = rpld.triggerValue == null ? 0 : rpld.triggerValue;
2018-05-22 10:11:50 +02:00
dcaLogData.PercChange = rpld.percChange;
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;
if (rpld.sellStrategies != null)
{
foreach (var ss in rpld.sellStrategies)
{
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;
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
System.DateTime rpldDateTime = new DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
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)
{
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
2019-10-19 12:14:40 +02:00
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(OffsetTimeSpan);
2018-05-22 10:11:50 +02:00
dcaLogData.FirstBoughtDate = ptFirstBoughtDate.DateTime;
}
else
{
2018-05-22 10:11:50 +02:00
dcaLogData.FirstBoughtDate = Constants.confMinDate;
}
_dcaLog.Add(dcaLogData);
}
2019-05-12 16:27:50 +02:00
foreach (var rpld in rawWatchModeLogData)
{
DCALogData dcaLogData = new DCALogData();
dcaLogData.Amount = rpld.totalAmount;
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
2019-10-19 12:14:40 +02:00
ptFirstBoughtDate = ptFirstBoughtDate.ToOffset(OffsetTimeSpan);
2019-05-12 16:27:50 +02:00
dcaLogData.FirstBoughtDate = ptFirstBoughtDate.DateTime;
}
else
{
dcaLogData.FirstBoughtDate = Constants.confMinDate;
}
_dcaLog.Add(dcaLogData);
}
2018-05-22 10:11:50 +02:00
}
private void BuildBuyLogData(dynamic rawBuyLogData)
{
foreach (var rbld in rawBuyLogData)
{
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;
if (rbld.positive != null)
{
buyLogData.IsTrailing = ((string)(rbld.positive)).IndexOf("trailing", StringComparison.InvariantCultureIgnoreCase) > -1;
buyLogData.IsTrue = ((string)(rbld.positive)).IndexOf("true", StringComparison.InvariantCultureIgnoreCase) > -1;
}
else
{
if (rbld.buyStrategies != null)
{
foreach (var bs in rbld.buyStrategies)
{
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;
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
// Is SOM?
2019-10-15 15:05:53 +02:00
buyLogData.IsSom = buyLogData.IsSom || buyStrategy.Name.Contains("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);
}
}
}
}