From b414ac942dceefcdfa0e6cd75b786ed1e9582fd1 Mon Sep 17 00:00:00 2001
From: woodser <woodser@protonmail.com>
Date: Thu, 15 Jun 2023 09:43:49 -0400
Subject: [PATCH] fix amounts in trade statistics view

---
 .../trade/statistics/TradeStatistics3.java    | 23 ++++++++-----------
 .../haveno/core/util/AveragePriceUtil.java    |  4 ++--
 .../desktop/main/market/MarketView.java       |  3 ++-
 .../main/market/trades/ChartCalculations.java | 18 +++++++--------
 .../trades/TradeStatistics3ListItem.java      |  7 ++----
 .../main/market/trades/TradesChartsView.java  | 17 +++++++-------
 6 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/core/src/main/java/haveno/core/trade/statistics/TradeStatistics3.java b/core/src/main/java/haveno/core/trade/statistics/TradeStatistics3.java
index ae06b693..8d0defa4 100644
--- a/core/src/main/java/haveno/core/trade/statistics/TradeStatistics3.java
+++ b/core/src/main/java/haveno/core/trade/statistics/TradeStatistics3.java
@@ -28,12 +28,8 @@ import haveno.common.util.CollectionUtils;
 import haveno.common.util.ExtraDataMapValidator;
 import haveno.common.util.JsonExclude;
 import haveno.common.util.Utilities;
-import haveno.core.locale.CurrencyUtil;
 import haveno.core.monetary.CryptoMoney;
-import haveno.core.monetary.CryptoExchangeRate;
 import haveno.core.monetary.Price;
-import haveno.core.monetary.TraditionalMoney;
-import haveno.core.monetary.TraditionalExchangeRate;
 import haveno.core.monetary.Volume;
 import haveno.core.offer.Offer;
 import haveno.core.offer.OfferPayload;
@@ -47,9 +43,10 @@ import haveno.network.p2p.storage.payload.PersistableNetworkPayload;
 import haveno.network.p2p.storage.payload.ProcessOncePersistableNetworkPayload;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
-import org.bitcoinj.core.Coin;
 
 import javax.annotation.Nullable;
+
+import java.math.BigInteger;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Arrays;
@@ -370,19 +367,17 @@ public final class TradeStatistics3 implements ProcessOncePersistableNetworkPayl
         return priceObj;
     }
 
-    public Coin getTradeAmount() {
-        return Coin.valueOf(amount);
+    public BigInteger getTradeAmount() {
+        return BigInteger.valueOf(amount);
     }
 
     public Volume getTradeVolume() {
+        Volume volume = this.volume;
         if (volume == null) {
-            if (getTradePrice().getMonetary() instanceof CryptoMoney) {
-                volume = new Volume(new CryptoExchangeRate((CryptoMoney) getTradePrice().getMonetary()).coinToCrypto(getTradeAmount()));
-            } else {
-                Volume exactVolume = new Volume(new TraditionalExchangeRate((TraditionalMoney) getTradePrice().getMonetary()).coinToTraditionalMoney(getTradeAmount()));
-                boolean isFiat = CurrencyUtil.isFiatCurrency(exactVolume.getCurrencyCode());
-                if (isFiat) volume = VolumeUtil.getRoundedFiatVolume(exactVolume);
-            }
+            Price price = getTradePrice();
+            this.volume = volume = price.getMonetary() instanceof CryptoMoney
+                    ? price.getVolumeByAmount(getTradeAmount())
+                    : VolumeUtil.getAdjustedVolume(price.getVolumeByAmount(getTradeAmount()), paymentMethod);
         }
         return volume;
     }
diff --git a/core/src/main/java/haveno/core/util/AveragePriceUtil.java b/core/src/main/java/haveno/core/util/AveragePriceUtil.java
index aca3d08b..4790b9f3 100644
--- a/core/src/main/java/haveno/core/util/AveragePriceUtil.java
+++ b/core/src/main/java/haveno/core/util/AveragePriceUtil.java
@@ -84,7 +84,7 @@ public class AveragePriceUtil {
 
         for (TradeStatistics3 item : list) {
             accumulatedVolume += item.getTradeVolume().getValue();
-            accumulatedAmount += item.getTradeAmount().getValue(); // Amount of BTC traded
+            accumulatedAmount += item.getTradeAmount().longValueExact(); // Amount of XMR traded
         }
         long averagePrice;
         double accumulatedAmountAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedAmount, CryptoMoney.SMALLEST_UNIT_EXPONENT);
@@ -110,7 +110,7 @@ public class AveragePriceUtil {
                     .orElse(usdBTCPrice);
             var bsqAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeVolume().getValue(),
                     CryptoMoney.SMALLEST_UNIT_EXPONENT);
-            var btcAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeAmount().getValue(),
+            var btcAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeAmount().longValueExact(),
                     CryptoMoney.SMALLEST_UNIT_EXPONENT);
             usdBsqList.add(new Tuple2<>(usdBTCPrice * btcAmount, bsqAmount));
         }
diff --git a/desktop/src/main/java/haveno/desktop/main/market/MarketView.java b/desktop/src/main/java/haveno/desktop/main/market/MarketView.java
index dfecbc65..c50bc16f 100644
--- a/desktop/src/main/java/haveno/desktop/main/market/MarketView.java
+++ b/desktop/src/main/java/haveno/desktop/main/market/MarketView.java
@@ -22,6 +22,7 @@ import haveno.common.util.Utilities;
 import haveno.core.locale.CurrencyUtil;
 import haveno.core.locale.Res;
 import haveno.core.offer.OfferPayload;
+import haveno.core.trade.HavenoUtils;
 import haveno.core.trade.statistics.TradeStatistics3;
 import haveno.core.trade.statistics.TradeStatistics3StorageService;
 import haveno.core.util.FormattingUtils;
@@ -189,7 +190,7 @@ public class MarketView extends ActivatableView<TabPane, Void> {
                     sb.append("Date: ").append(DisplayUtils.formatDateTime(tradeStatistics3.getDate())).append("\n")
                             .append("Market: ").append(CurrencyUtil.getCurrencyPair(tradeStatistics3.getCurrency())).append("\n")
                             .append("Price: ").append(FormattingUtils.formatPrice(tradeStatistics3.getTradePrice())).append("\n")
-                            .append("Amount: ").append(formatter.formatCoin(tradeStatistics3.getTradeAmount())).append("\n")
+                            .append("Amount: ").append(HavenoUtils.formatXmr(tradeStatistics3.getTradeAmount())).append("\n")
                             .append("Volume: ").append(VolumeUtil.formatVolume(tradeStatistics3.getTradeVolume())).append("\n")
                             .append("Payment method: ").append(Res.get(tradeStatistics3.getPaymentMethodId())).append("\n")
                             .append("ReferralID: ").append(tradeStatistics3.getExtraDataMap().get(OfferPayload.REFERRAL_ID));
diff --git a/desktop/src/main/java/haveno/desktop/main/market/trades/ChartCalculations.java b/desktop/src/main/java/haveno/desktop/main/market/trades/ChartCalculations.java
index f12af422..0a2e8f1a 100644
--- a/desktop/src/main/java/haveno/desktop/main/market/trades/ChartCalculations.java
+++ b/desktop/src/main/java/haveno/desktop/main/market/trades/ChartCalculations.java
@@ -21,13 +21,13 @@ import com.google.common.annotations.VisibleForTesting;
 import haveno.common.util.MathUtils;
 import haveno.core.locale.CurrencyUtil;
 import haveno.core.monetary.CryptoMoney;
+import haveno.core.monetary.TraditionalMoney;
 import haveno.core.trade.statistics.TradeStatistics3;
 import haveno.desktop.main.market.trades.charts.CandleData;
 import haveno.desktop.util.DisplayUtils;
 import javafx.scene.chart.XYChart;
 import javafx.util.Pair;
 import lombok.Getter;
-import org.bitcoinj.core.Coin;
 
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -211,14 +211,14 @@ public class ChartCalculations {
     }
 
     private static long getAveragePrice(List<TradeStatistics3> tradeStatisticsList) {
-        long accumulatedAmount = 0;
+        long accumulatedAmount = 0; // TODO: use BigInteger
         long accumulatedVolume = 0;
         for (TradeStatistics3 tradeStatistics : tradeStatisticsList) {
             accumulatedAmount += tradeStatistics.getAmount();
             accumulatedVolume += tradeStatistics.getTradeVolume().getValue();
         }
 
-        double accumulatedVolumeAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedVolume, Coin.SMALLEST_UNIT_EXPONENT);
+        double accumulatedVolumeAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedVolume, 4 + TraditionalMoney.SMALLEST_UNIT_EXPONENT);
         return MathUtils.roundDoubleToLong(accumulatedVolumeAsDouble / accumulatedAmount);
     }
 
@@ -232,7 +232,7 @@ public class ChartCalculations {
         long close = 0;
         long high = 0;
         long low = 0;
-        long accumulatedVolume = 0;
+        long accumulatedVolume = 0; // TODO: use BigInteger
         long accumulatedAmount = 0;
         long numTrades = set.size();
         List<Long> tradePrices = new ArrayList<>();
@@ -243,7 +243,7 @@ public class ChartCalculations {
             high = (high != 0) ? Math.max(high, tradePriceAsLong) : tradePriceAsLong;
 
             accumulatedVolume += item.getTradeVolume().getValue();
-            accumulatedAmount += item.getTradeAmount().getValue();
+            accumulatedAmount += item.getTradeAmount().longValueExact();
             tradePrices.add(tradePriceAsLong);
         }
         Collections.sort(tradePrices);
@@ -262,11 +262,11 @@ public class ChartCalculations {
         boolean isBullish;
         if (CurrencyUtil.isCryptoCurrency(currencyCode)) {
             isBullish = close < open;
-            double accumulatedAmountAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedAmount, CryptoMoney.SMALLEST_UNIT_EXPONENT);
+            double accumulatedAmountAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedAmount, 4 + CryptoMoney.SMALLEST_UNIT_EXPONENT);
             averagePrice = MathUtils.roundDoubleToLong(accumulatedAmountAsDouble / accumulatedVolume);
         } else {
             isBullish = close > open;
-            double accumulatedVolumeAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedVolume, Coin.SMALLEST_UNIT_EXPONENT);
+            double accumulatedVolumeAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedVolume, 4 + TraditionalMoney.SMALLEST_UNIT_EXPONENT);
             averagePrice = MathUtils.roundDoubleToLong(accumulatedVolumeAsDouble / accumulatedAmount);
         }
 
@@ -277,10 +277,10 @@ public class ChartCalculations {
                 DisplayUtils.formatDate(dateFrom) + " - " + DisplayUtils.formatDate(dateTo);
 
         // We do not need precision, so we scale down before multiplication otherwise we could get an overflow.
-        averageUsdPrice = (long) MathUtils.scaleDownByPowerOf10((double) averageUsdPrice, 4);
+        averageUsdPrice = (long) MathUtils.scaleDownByPowerOf10((double) averageUsdPrice, TraditionalMoney.SMALLEST_UNIT_EXPONENT);
         long volumeInUsd = averageUsdPrice * (long) MathUtils.scaleDownByPowerOf10((double) accumulatedAmount, 4);
         // We store USD value without decimals as its only total volume, no precision is needed.
-        volumeInUsd = (long) MathUtils.scaleDownByPowerOf10((double) volumeInUsd, 4);
+        volumeInUsd = (long) MathUtils.scaleDownByPowerOf10((double) volumeInUsd, TraditionalMoney.SMALLEST_UNIT_EXPONENT);
         return new CandleData(tick, open, close, high, low, averagePrice, medianPrice, accumulatedAmount, accumulatedVolume,
                 numTrades, isBullish, dateString, volumeInUsd);
     }
diff --git a/desktop/src/main/java/haveno/desktop/main/market/trades/TradeStatistics3ListItem.java b/desktop/src/main/java/haveno/desktop/main/market/trades/TradeStatistics3ListItem.java
index 2b5bf236..8bbf7b06 100644
--- a/desktop/src/main/java/haveno/desktop/main/market/trades/TradeStatistics3ListItem.java
+++ b/desktop/src/main/java/haveno/desktop/main/market/trades/TradeStatistics3ListItem.java
@@ -19,10 +19,10 @@ package haveno.desktop.main.market.trades;
 
 import haveno.core.locale.CurrencyUtil;
 import haveno.core.locale.Res;
+import haveno.core.trade.HavenoUtils;
 import haveno.core.trade.statistics.TradeStatistics3;
 import haveno.core.util.FormattingUtils;
 import haveno.core.util.VolumeUtil;
-import haveno.core.util.coin.CoinFormatter;
 import haveno.desktop.util.DisplayUtils;
 import lombok.experimental.Delegate;
 import org.jetbrains.annotations.Nullable;
@@ -30,7 +30,6 @@ import org.jetbrains.annotations.Nullable;
 public class TradeStatistics3ListItem {
     @Delegate
     private final TradeStatistics3 tradeStatistics3;
-    private final CoinFormatter coinFormatter;
     private final boolean showAllTradeCurrencies;
     private String dateString;
     private String market;
@@ -40,10 +39,8 @@ public class TradeStatistics3ListItem {
     private String amountString;
 
     public TradeStatistics3ListItem(@Nullable TradeStatistics3 tradeStatistics3,
-                                    CoinFormatter coinFormatter,
                                     boolean showAllTradeCurrencies) {
         this.tradeStatistics3 = tradeStatistics3;
-        this.coinFormatter = coinFormatter;
         this.showAllTradeCurrencies = showAllTradeCurrencies;
     }
 
@@ -87,7 +84,7 @@ public class TradeStatistics3ListItem {
 
     public String getAmountString() {
         if (amountString == null) {
-            amountString = tradeStatistics3 != null ? coinFormatter.formatCoin(tradeStatistics3.getTradeAmount(), 4) : "";
+            amountString = tradeStatistics3 != null ? HavenoUtils.formatXmr(getAmount(), false, 4) : "";
         }
         return amountString;
     }
diff --git a/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java b/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java
index 7f8d891c..4553380e 100644
--- a/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java
+++ b/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java
@@ -26,6 +26,7 @@ import haveno.common.util.Tuple3;
 import haveno.core.locale.CurrencyUtil;
 import haveno.core.locale.Res;
 import haveno.core.monetary.Price;
+import haveno.core.trade.HavenoUtils;
 import haveno.core.trade.statistics.TradeStatistics3;
 import haveno.core.user.CookieKey;
 import haveno.core.user.User;
@@ -78,7 +79,6 @@ import javafx.scene.text.Text;
 import javafx.stage.Stage;
 import javafx.util.Callback;
 import javafx.util.StringConverter;
-import org.bitcoinj.core.Coin;
 import org.fxmisc.easybind.EasyBind;
 import org.fxmisc.easybind.Subscription;
 import org.fxmisc.easybind.monadic.MonadicBinding;
@@ -377,7 +377,6 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
         CompletableFuture.supplyAsync(() -> {
             return model.tradeStatisticsByCurrency.stream()
                     .map(tradeStatistics -> new TradeStatistics3ListItem(tradeStatistics,
-                            coinFormatter,
                             model.showAllTradeCurrenciesProperty.get()))
                     .collect(Collectors.toCollection(FXCollections::observableArrayList));
         }).whenComplete((listItems, throwable) -> {
@@ -438,7 +437,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
 
         String details = showAllTradeCurrencies ? "all-markets" : model.getCurrencyCode();
         GUIUtil.exportCSV("trade-statistics-" + details + ".csv", headerConverter, contentConverter,
-                new TradeStatistics3ListItem(null, coinFormatter, showAllTradeCurrencies),
+                new TradeStatistics3ListItem(null, showAllTradeCurrencies),
                 sortedList,
                 (Stage) root.getScene().getWindow());
     }
@@ -517,7 +516,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
 
         volumeAxisX = new NumberAxis(0, MAX_TICKS + 1, 1);
         volumeAxisY = new NumberAxis();
-        volumeChart = getVolumeChart(volumeAxisX, volumeAxisY, volumeSeries, "BTC");
+        volumeChart = getVolumeChart(volumeAxisX, volumeAxisY, volumeSeries, "XMR");
 
         volumeInUsdAxisX = new NumberAxis(0, MAX_TICKS + 1, 1);
         NumberAxis volumeInUsdAxisY = new NumberAxis();
@@ -557,8 +556,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
         axisY.setTickLabelFormatter(new StringConverter<>() {
             @Override
             public String toString(Number volume) {
-                return currency.equals("BTC") ?
-                        coinFormatter.formatCoin(Coin.valueOf(MathUtils.doubleToLong((double) volume))) :
+                return currency.equals("XMR") ?
+                        HavenoUtils.formatXmr(MathUtils.doubleToLong((double) volume)) :
                         VolumeUtil.formatLargeFiatWithUnitPostFix((double) volume, "USD");
             }
 
@@ -568,10 +567,10 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
             }
         });
 
-        StringConverter<Number> btcStringConverter = new StringConverter<>() {
+        StringConverter<Number> xmrStringConverter = new StringConverter<>() {
             @Override
             public String toString(Number volume) {
-                return coinFormatter.formatCoinWithCode(Coin.valueOf((long) volume));
+                return HavenoUtils.formatXmr((long) volume, true);
             }
 
             @Override
@@ -579,7 +578,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
                 return null;
             }
         };
-        VolumeChart volumeChart = new VolumeChart(axisX, axisY, btcStringConverter);
+        VolumeChart volumeChart = new VolumeChart(axisX, axisY, xmrStringConverter);
         volumeChart.setId("volume-chart");
         volumeChart.setData(FXCollections.observableArrayList(List.of(series)));
         volumeChart.setMinHeight(138);