package io.bitsquare.trade.statistics;
import io.bitsquare.common.util.MathUtils;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.trade.offer.Offer;
import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.ExchangeRate;
import org.bitcoinj.utils.Fiat;
import org.bitcoinj.utils.MonetaryFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.concurrent.Immutable;
import java.text.DecimalFormat;
@Immutable
public final class TradeStatisticsForJson {
private static final Logger log = LoggerFactory.getLogger(TradeStatisticsForJson.class);
public final String currency;
public final Offer.Direction direction;
public final long tradePrice;
public final long tradeAmount;
public final long tradeDate;
public final String paymentMethod;
public final long offerDate;
public final boolean useMarketBasedPrice;
public final double marketPriceMargin;
public final long offerAmount;
public final long offerMinAmount;
public final String offerId;
public final String depositTxId;
// primaryMarket fields are based on industry standard where primaryMarket is always in the focus (in the app BTC is always in the focus - will be changed in a larger refactoring once)
public String currencyPair;
public Offer.Direction primaryMarketDirection;
public String tradePriceDisplayString;
public String primaryMarketTradeAmountDisplayString;
public String primaryMarketTradeVolumeDisplayString;
public long primaryMarketTradePrice;
public long primaryMarketTradeAmount;
public long primaryMarketTradeVolume;
public TradeStatisticsForJson(TradeStatistics tradeStatistics) {
this.direction = tradeStatistics.direction;
this.currency = tradeStatistics.currency;
this.paymentMethod = tradeStatistics.paymentMethod;
this.offerDate = tradeStatistics.offerDate;
this.useMarketBasedPrice = tradeStatistics.useMarketBasedPrice;
this.marketPriceMargin = tradeStatistics.marketPriceMargin;
this.offerAmount = tradeStatistics.offerAmount;
this.offerMinAmount = tradeStatistics.offerMinAmount;
this.offerId = tradeStatistics.getOfferId();
this.tradePrice = tradeStatistics.tradePrice;
this.tradeAmount = tradeStatistics.tradeAmount;
this.tradeDate = tradeStatistics.tradeDate;
this.depositTxId = tradeStatistics.depositTxId;
try {
MonetaryFormat fiatFormat = MonetaryFormat.FIAT.repeatOptionalDecimals(0, 0);
MonetaryFormat coinFormat = MonetaryFormat.BTC.minDecimals(2).repeatOptionalDecimals(1, 6);
final Fiat tradePriceAsFiat = getTradePrice();
if (CurrencyUtil.isCryptoCurrency(currency)) {
primaryMarketDirection = direction == Offer.Direction.BUY ? Offer.Direction.SELL : Offer.Direction.BUY;
final double value = tradePriceAsFiat.value != 0 ? 10000D / tradePriceAsFiat.value : 0;
DecimalFormat decimalFormat = new DecimalFormat("#.#");
decimalFormat.setMaximumFractionDigits(8);
tradePriceDisplayString = decimalFormat.format(MathUtils.roundDouble(value, 8)).replace(",", ".");
currencyPair = currency + "/" + "BTC";
primaryMarketTradePrice = MathUtils.roundDoubleToLong(MathUtils.scaleUpByPowerOf10(value, 8));
primaryMarketTradeVolumeDisplayString = coinFormat.noCode().format(getTradeAmount()).toString();
primaryMarketTradeAmountDisplayString = fiatFormat.noCode().format(getTradeVolume()).toString();
primaryMarketTradeAmount = (long) MathUtils.scaleUpByPowerOf10(getTradeVolume().longValue(), 4);
primaryMarketTradeVolume = getTradeAmount().longValue();
} else {
primaryMarketDirection = direction;
currencyPair = "BTC/" + currency;
tradePriceDisplayString = fiatFormat.noCode().format(tradePriceAsFiat).toString();
primaryMarketTradePrice = (long) MathUtils.scaleUpByPowerOf10(tradePriceAsFiat.longValue(), 4);
primaryMarketTradeAmountDisplayString = coinFormat.noCode().format(getTradeAmount()).toString();
primaryMarketTradeVolumeDisplayString = fiatFormat.noCode().format(getTradeVolume()).toString();
primaryMarketTradeAmount = getTradeAmount().longValue();
primaryMarketTradeVolume = (long) MathUtils.scaleUpByPowerOf10(getTradeVolume().longValue(), 4);
}
} catch (Throwable t) {
log.error("Error at setDisplayStrings: " + t.getMessage());
}
}
public Fiat getTradePrice() {
return Fiat.valueOf(currency, tradePrice);
}
public Coin getTradeAmount() {
return Coin.valueOf(tradeAmount);
}
public Fiat getTradeVolume() {
return new ExchangeRate(getTradePrice()).coinToFiat(getTradeAmount());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof TradeStatisticsForJson)) return false;
TradeStatisticsForJson that = (TradeStatisticsForJson) o;
if (tradePrice != that.tradePrice) return false;
if (tradeAmount != that.tradeAmount) return false;
if (tradeDate != that.tradeDate) return false;
if (offerDate != that.offerDate) return false;
if (useMarketBasedPrice != that.useMarketBasedPrice) return false;
if (Double.compare(that.marketPriceMargin, marketPriceMargin) != 0) return false;
if (offerAmount != that.offerAmount) return false;
if (offerMinAmount != that.offerMinAmount) return false;
if (tradePriceDisplayString != null ? !tradePriceDisplayString.equals(that.tradePriceDisplayString) : that.tradePriceDisplayString != null)
return false;
if (primaryMarketTradeAmountDisplayString != null ? !primaryMarketTradeAmountDisplayString.equals(that.primaryMarketTradeAmountDisplayString) : that.primaryMarketTradeAmountDisplayString != null)
return false;
if (primaryMarketTradeVolumeDisplayString != null ? !primaryMarketTradeVolumeDisplayString.equals(that.primaryMarketTradeVolumeDisplayString) : that.primaryMarketTradeVolumeDisplayString != null)
return false;
if (currency != null ? !currency.equals(that.currency) : that.currency != null) return false;
if (direction != that.direction) return false;
if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null)
return false;
if (offerId != null ? !offerId.equals(that.offerId) : that.offerId != null) return false;
return !(depositTxId != null ? !depositTxId.equals(that.depositTxId) : that.depositTxId != null);
}
@Override
public int hashCode() {
int result;
long temp;
result = tradePriceDisplayString != null ? tradePriceDisplayString.hashCode() : 0;
result = 31 * result + (primaryMarketTradeAmountDisplayString != null ? primaryMarketTradeAmountDisplayString.hashCode() : 0);
result = 31 * result + (primaryMarketTradeVolumeDisplayString != null ? primaryMarketTradeVolumeDisplayString.hashCode() : 0);
result = 31 * result + (currency != null ? currency.hashCode() : 0);
result = 31 * result + (direction != null ? direction.hashCode() : 0);
result = 31 * result + (int) (tradePrice ^ (tradePrice >>> 32));
result = 31 * result + (int) (tradeAmount ^ (tradeAmount >>> 32));
result = 31 * result + (int) (tradeDate ^ (tradeDate >>> 32));
result = 31 * result + (paymentMethod != null ? paymentMethod.hashCode() : 0);
result = 31 * result + (int) (offerDate ^ (offerDate >>> 32));
result = 31 * result + (useMarketBasedPrice ? 1 : 0);
temp = Double.doubleToLongBits(marketPriceMargin);
result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (int) (offerAmount ^ (offerAmount >>> 32));
result = 31 * result + (int) (offerMinAmount ^ (offerMinAmount >>> 32));
result = 31 * result + (offerId != null ? offerId.hashCode() : 0);
result = 31 * result + (depositTxId != null ? depositTxId.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "TradeStatisticsForJson{" +
"currency='" + currency + '\'' +
", direction=" + direction +
", tradePrice=" + tradePrice +
", tradeAmount=" + tradeAmount +
", tradeDate=" + tradeDate +
", paymentMethod='" + paymentMethod + '\'' +
", offerDate=" + offerDate +
", useMarketBasedPrice=" + useMarketBasedPrice +
", marketPriceMargin=" + marketPriceMargin +
", offerAmount=" + offerAmount +
", offerMinAmount=" + offerMinAmount +
", offerId='" + offerId + '\'' +
", depositTxId='" + depositTxId + '\'' +
", tradePriceDisplayString='" + tradePriceDisplayString + '\'' +
", tradeAmountDisplayString='" + primaryMarketTradeAmountDisplayString + '\'' +
", tradeVolumeDisplayString='" + primaryMarketTradeVolumeDisplayString + '\'' +
", currencyPair='" + currencyPair + '\'' +
", primaryMarketTradeAmount=" + primaryMarketTradeAmount +
", primaryMarketTradeVolume=" + primaryMarketTradeVolume +
'}';
}
}