/// <summary> /// Calculate a purchase's worth, delta, boughtAt and profit /// </summary> /// <param name="purchase"></param> /// <returns></returns> public async static Task <PurchaseModel> UpdatePurchase(PurchaseModel purchase) { string crypto = purchase.Crypto; if (purchase.Current <= 0 || (DateTime.Now - purchase.LastUpdate).TotalSeconds > 20) { purchase.Current = await Ioc.Default.GetService <ICryptoCompare>().GetPrice_Extension( purchase.Crypto, purchase.Currency); } var curr = purchase.Current; purchase.Worth = NumberHelper.Rounder(curr * purchase.CryptoQty); /// If the user has also filled the invested quantity, we can calculate everything else if (purchase.InvestedQty >= 0) { double priceBought = purchase.InvestedQty / purchase.CryptoQty; priceBought = NumberHelper.Rounder(priceBought); var diff = Math.Round((curr - priceBought) * purchase.CryptoQty, 4); purchase.Delta = Math.Round(100 * diff / purchase.InvestedQty, 2); purchase.BoughtAt = priceBought; if (purchase.Delta > 100) { purchase.Delta -= 100; } purchase.Profit = Math.Round(diff, 2); purchase.ProfitFG = (diff < 0) ? ColorConstants.GetColorBrush("pastel_red") : ColorConstants.GetColorBrush("pastel_green"); } if (purchase.InvestedQty == 0) { purchase.Delta = 0; } return(purchase); }
public object Convert(object val, Type targetType, object param, string lang) { if (val != null) { var vals = (val as List <double>); color = (vals[vals.Count - 1] > vals[0]) ? SKColor.Parse(ColorConstants.GetColorBrush("pastel_green").Color.ToString()) : SKColor.Parse(ColorConstants.GetColorBrush("pastel_red").Color.ToString()); var entries = vals.ConvertAll(PointConverter); Chart chart = new LineChart() { Entries = entries, IsAnimated = false, LineAreaAlpha = 0, PointAreaAlpha = 0, BackgroundColor = SKColors.Transparent, LabelColor = SKColors.Green, LineMode = LineMode.Straight, LineSize = 1, PointSize = 1, MinValue = entries.Min(x => x.Value), MaxValue = entries.Max(x => x.Value), }; return(chart); } else { return new LineChart() { Entries = new List <ChartEntry>() { new ChartEntry(0) }, BackgroundColor = SKColors.Transparent, IsAnimated = false } }; }
/// ############################################################################################### /// Update the chart of the historic values of the portfolio private async Task UpdatePortfolioChart() { var nPurchases = vm.Portfolio.Count; if (nPurchases == 0) { return; } /// Optimize by only getting historic for different cryptos var uniqueCryptos = new HashSet <string>(vm.Portfolio.Select(x => x.Crypto)).ToList(); /// Get historic for each unique crypto, get invested qty, and multiply /// to get the worth of each crypto to the user's wallet var cryptoQties = new List <double>(); var cryptoWorth = new List <List <double> >(); var histos = new List <List <HistoricPrice> >(nPurchases); foreach (var crypto in uniqueCryptos) { var histo = await Ioc.Default.GetService <ICryptoCompare>().GetHistoric_(crypto, timeUnit, limit, aggregate); var cryptoQty = vm.Portfolio.Where(x => x.Crypto == crypto).Sum(x => x.CryptoQty); cryptoWorth.Add(histo.Select(x => x.Average * cryptoQty).ToList()); histos.Add(histo); } /// There might be young cryptos that didnt exist in the past, so take the common minimum var minCommon = histos.Min(x => x.Count); if (minCommon == 1) { return; } /// Check if all arrays are equal length, if not, remove the leading values var sameLength = cryptoWorth.All(x => x.Count == cryptoWorth[0].Count); if (!sameLength) { for (int i = 0; i < histos.Count; i++) { histos[i] = histos[i].Skip(Math.Max(0, histos[i].Count() - minCommon)).ToList(); } } var worth_arr = new List <double>(); var dates_arr = histos[0].Select(kk => kk.DateTime).ToList(); for (int i = 0; i < minCommon; i++) { worth_arr.Add(cryptoWorth.Select(x => x[i]).Sum()); } /// Create List for chart var chartData = new List <ChartPoint>(); for (int i = 0; i < minCommon; i++) { chartData.Add(new ChartPoint { Date = dates_arr.ElementAt(i), Value = (float)worth_arr[i], Volume = 0 }); } vm.Chart.ChartData = chartData; var temp = GraphHelper.AdjustLinearAxis(new ChartStyling(), timeSpan); vm.Chart.LabelFormat = temp.LabelFormat; vm.Chart.Minimum = temp.Minimum; vm.Chart.MajorStepUnit = temp.MajorStepUnit; vm.Chart.MajorStep = temp.MajorStep; vm.Chart.TickInterval = temp.TickInterval; vm.Chart.ChartStroke = (vm.TotalDelta >= 0) ? ColorConstants.GetColorBrush("pastel_green") : ColorConstants.GetColorBrush("pastel_red"); /// Calculate min-max to adjust axis var MinMax = GraphHelper.GetMinMaxOfArray(chartData.Select(d => d.Value).ToList()); vm.Chart.PricesMinMax = GraphHelper.OffsetMinMaxForChart(MinMax.Min, MinMax.Max); vm.Chart.VolumeMax = GraphHelper.GetMaxOfVolume(chartData); vm.Chart.VolumeMax = (vm.Chart.VolumeMax == 0) ? 10 : vm.Chart.VolumeMax; vm.Chart.IsLoading = false; }
public object Convert(object val, Type targetType, object param, string lang) => (double)val >= 0 ? ColorConstants.GetColorBrush("pastel_green") : ColorConstants.GetColorBrush("pastel_red");