traditional currency price to 8 decimals, volume to 4 decimals #621

This commit is contained in:
woodser 2023-05-28 18:13:41 -04:00
parent 69b0d54c7e
commit f3f1c41b27
5 changed files with 27 additions and 10 deletions

View file

@ -204,7 +204,7 @@ public final class TraditionalMoney implements Monetary, Comparable<TraditionalM
return FRIENDLY_FORMAT.code(0, currencyCode).format(this).toString();
}
private static final MonetaryFormat PLAIN_FORMAT = MonetaryFormat.FIAT.minDecimals(0).repeatOptionalDecimals(1, 8).noCode();
private static final MonetaryFormat PLAIN_FORMAT = MonetaryFormat.FIAT.minDecimals(0).repeatOptionalDecimals(1, TraditionalMoney.SMALLEST_UNIT_EXPONENT).noCode();
/**
* <p>

View file

@ -22,6 +22,7 @@ import haveno.core.locale.CurrencyUtil;
import haveno.core.locale.Res;
import haveno.core.monetary.CryptoMoney;
import haveno.core.monetary.Price;
import haveno.core.monetary.TraditionalMoney;
import haveno.core.monetary.Volume;
import haveno.core.payment.payload.PaymentMethod;
import haveno.core.trade.HavenoUtils;
@ -64,7 +65,7 @@ public class OfferForJson {
public long primaryMarketMinVolume;
@JsonIgnore
transient private final MonetaryFormat traditionalFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
transient private final MonetaryFormat traditionalFormat = new MonetaryFormat().shift(0).minDecimals(TraditionalMoney.SMALLEST_UNIT_EXPONENT).repeatOptionalDecimals(0, 0);
@JsonIgnore
transient private final MonetaryFormat cryptoFormat = new MonetaryFormat().shift(0).minDecimals(CryptoMoney.SMALLEST_UNIT_EXPONENT).repeatOptionalDecimals(0, 0);
@JsonIgnore

View file

@ -1434,6 +1434,8 @@ public abstract class Trade implements Tradable, Model {
volumeByAmount = VolumeUtil.getAdjustedVolumeForHalCash(volumeByAmount);
else if (CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()))
volumeByAmount = VolumeUtil.getRoundedFiatVolume(volumeByAmount);
else if (CurrencyUtil.isTraditionalCurrency(offer.getCurrencyCode()))
volumeByAmount = VolumeUtil.getRoundedTraditionalVolume(volumeByAmount);
}
return volumeByAmount;
} else {

View file

@ -29,7 +29,9 @@ public class FormattingUtils {
public final static String RANGE_SEPARATOR = " - ";
private static final MonetaryFormat traditionalPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
private static final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
private static final MonetaryFormat nonFiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(8).repeatOptionalDecimals(0, 0);
private static final MonetaryFormat traditionalFormat = new MonetaryFormat().shift(0).minDecimals(TraditionalMoney.SMALLEST_UNIT_EXPONENT).repeatOptionalDecimals(0, 0);
private static final MonetaryFormat cryptoFormat = new MonetaryFormat().shift(0).minDecimals(CryptoMoney.SMALLEST_UNIT_EXPONENT).repeatOptionalDecimals(0, 0);
private static final DecimalFormat decimalFormat = new DecimalFormat("#.#");
@ -151,11 +153,11 @@ public class FormattingUtils {
}
public static String formatPrice(Price price, boolean appendCurrencyCode) {
return formatPrice(price, getMonetaryFormat(price.getCurrencyCode()), appendCurrencyCode);
return formatPrice(price, getPriceMonetaryFormat(price.getCurrencyCode()), appendCurrencyCode);
}
public static String formatPrice(Price price) {
return formatPrice(price, getMonetaryFormat(price.getCurrencyCode()), false);
return formatPrice(price, getPriceMonetaryFormat(price.getCurrencyCode()), false);
}
public static String formatMarketPrice(double price, String currencyCode) {
@ -292,6 +294,10 @@ public class FormattingUtils {
}
public static MonetaryFormat getMonetaryFormat(String currencyCode) {
return CurrencyUtil.isTraditionalCurrency(currencyCode) ? traditionalPriceFormat : cryptoFormat;
return CurrencyUtil.isTraditionalCurrency(currencyCode) ? traditionalFormat : cryptoFormat;
}
public static MonetaryFormat getPriceMonetaryFormat(String currencyCode) {
return CurrencyUtil.isFiatCurrency(currencyCode) ? fiatPriceFormat : nonFiatPriceFormat;
}
}

View file

@ -40,13 +40,21 @@ public class VolumeUtil {
private static final MonetaryFormat FIAT_VOLUME_FORMAT = new MonetaryFormat().shift(0).minDecimals(0).repeatOptionalDecimals(0, 0);
private static final MonetaryFormat TRADITIONAL_VOLUME_FORMAT = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
private static double EXPONENT = Math.pow(10, TraditionalMoney.SMALLEST_UNIT_EXPONENT); // 1000000000000 with precision 8
public static Volume getRoundedFiatVolume(Volume volumeByAmount) {
// We want to get rounded to 1 unit of the fiat currency, e.g. 1 EUR.
return getAdjustedFiatVolume(volumeByAmount, 1);
}
public static Volume getRoundedTraditionalVolume(Volume volumeByAmount) {
DecimalFormat decimalFormat = new DecimalFormat("#.####");
double roundedVolume = Double.parseDouble(decimalFormat.format(Double.parseDouble(volumeByAmount.toString())));
return Volume.parse(String.valueOf(roundedVolume), volumeByAmount.getCurrencyCode());
}
public static Volume getAdjustedVolumeForHalCash(Volume volumeByAmount) {
// EUR has precision 8 and we want multiple of 10 so we divide by 1000000000 then
// EUR has precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of 10 so we divide by EXPONENT then
// round and multiply with 10
return getAdjustedFiatVolume(volumeByAmount, 10);
}
@ -59,9 +67,9 @@ public class VolumeUtil {
* @return The adjusted Fiat volume
*/
public static Volume getAdjustedFiatVolume(Volume volumeByAmount, int factor) {
// Fiat currencies use precision 8 and we want multiple of factor so we divide by 100000000 * factor then
// round and multiply with factor
long roundedVolume = Math.round((double) volumeByAmount.getValue() / (100000000d * factor)) * factor;
// Fiat currencies use precision TraditionalMoney.SMALLEST_UNIT_EXPONENT and we want multiple of factor so we divide
// by EXPONENT * factor then round and multiply with factor
long roundedVolume = Math.round((double) volumeByAmount.getValue() / (EXPONENT * factor)) * factor;
// Smallest allowed volume is factor (e.g. 10 EUR or 1 EUR,...)
roundedVolume = Math.max(factor, roundedVolume);
return Volume.parse(String.valueOf(roundedVolume), volumeByAmount.getCurrencyCode());