put trade price into trade and contract

This commit is contained in:
Manfred Karrer 2016-04-15 02:07:58 +02:00
parent 13a62b1342
commit bc07df2d7a
29 changed files with 139 additions and 51 deletions

View file

@ -43,8 +43,8 @@ public final class BuyerAsTakerTrade extends BuyerTrade implements TakerTrade {
// Constructor, initialization // Constructor, initialization
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public BuyerAsTakerTrade(Offer offer, Coin tradeAmount, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) { public BuyerAsTakerTrade(Offer offer, Coin tradeAmount, long tradePrice, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) {
super(offer, tradeAmount, tradingPeerNodeAddress, storage); super(offer, tradeAmount, tradePrice, tradingPeerNodeAddress, storage);
} }
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {

View file

@ -38,8 +38,8 @@ public abstract class BuyerTrade extends Trade {
private static final Logger log = LoggerFactory.getLogger(BuyerAsOffererTrade.class); private static final Logger log = LoggerFactory.getLogger(BuyerAsOffererTrade.class);
BuyerTrade(Offer offer, Coin tradeAmount, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) { BuyerTrade(Offer offer, Coin tradeAmount, long tradePrice, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) {
super(offer, tradeAmount, tradingPeerNodeAddress, storage); super(offer, tradeAmount, tradePrice, tradingPeerNodeAddress, storage);
} }
BuyerTrade(Offer offer, Storage<? extends TradableList> storage) { BuyerTrade(Offer offer, Storage<? extends TradableList> storage) {
@ -65,7 +65,7 @@ public abstract class BuyerTrade extends Trade {
log::warn); log::warn);
} }
} }
@Override @Override
public Coin getPayoutAmount() { public Coin getPayoutAmount() {
checkNotNull(getTradeAmount(), "Invalid state: getTradeAmount() = null"); checkNotNull(getTradeAmount(), "Invalid state: getTradeAmount() = null");

View file

@ -25,6 +25,7 @@ import io.bitsquare.p2p.NodeAddress;
import io.bitsquare.payment.PaymentAccountContractData; import io.bitsquare.payment.PaymentAccountContractData;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import java.util.Arrays; import java.util.Arrays;
@ -40,6 +41,7 @@ public final class Contract implements Payload {
public final Offer offer; public final Offer offer;
private final long tradeAmount; private final long tradeAmount;
private final long tradePrice;
public final String takeOfferFeeTxID; public final String takeOfferFeeTxID;
public final NodeAddress arbitratorNodeAddress; public final NodeAddress arbitratorNodeAddress;
private final boolean isBuyerOffererAndSellerTaker; private final boolean isBuyerOffererAndSellerTaker;
@ -64,6 +66,7 @@ public final class Contract implements Payload {
public Contract(Offer offer, public Contract(Offer offer,
Coin tradeAmount, Coin tradeAmount,
Fiat tradePrice,
String takeOfferFeeTxID, String takeOfferFeeTxID,
NodeAddress buyerNodeAddress, NodeAddress buyerNodeAddress,
NodeAddress sellerNodeAddress, NodeAddress sellerNodeAddress,
@ -80,6 +83,7 @@ public final class Contract implements Payload {
byte[] offererBtcPubKey, byte[] offererBtcPubKey,
byte[] takerBtcPubKey) { byte[] takerBtcPubKey) {
this.offer = offer; this.offer = offer;
this.tradePrice = tradePrice.value;
this.buyerNodeAddress = buyerNodeAddress; this.buyerNodeAddress = buyerNodeAddress;
this.sellerNodeAddress = sellerNodeAddress; this.sellerNodeAddress = sellerNodeAddress;
this.tradeAmount = tradeAmount.value; this.tradeAmount = tradeAmount.value;
@ -154,6 +158,10 @@ public final class Contract implements Payload {
return Coin.valueOf(tradeAmount); return Coin.valueOf(tradeAmount);
} }
public Fiat getTradePrice() {
return Fiat.valueOf(offer.getCurrencyCode(), tradePrice);
}
public NodeAddress getBuyerNodeAddress() { public NodeAddress getBuyerNodeAddress() {
return buyerNodeAddress; return buyerNodeAddress;
} }
@ -171,6 +179,7 @@ public final class Contract implements Payload {
Contract contract = (Contract) o; Contract contract = (Contract) o;
if (tradeAmount != contract.tradeAmount) return false; if (tradeAmount != contract.tradeAmount) return false;
if (tradePrice != contract.tradePrice) return false;
if (isBuyerOffererAndSellerTaker != contract.isBuyerOffererAndSellerTaker) return false; if (isBuyerOffererAndSellerTaker != contract.isBuyerOffererAndSellerTaker) return false;
if (offer != null ? !offer.equals(contract.offer) : contract.offer != null) return false; if (offer != null ? !offer.equals(contract.offer) : contract.offer != null) return false;
if (takeOfferFeeTxID != null ? !takeOfferFeeTxID.equals(contract.takeOfferFeeTxID) : contract.takeOfferFeeTxID != null) if (takeOfferFeeTxID != null ? !takeOfferFeeTxID.equals(contract.takeOfferFeeTxID) : contract.takeOfferFeeTxID != null)
@ -206,6 +215,7 @@ public final class Contract implements Payload {
public int hashCode() { public int hashCode() {
int result = offer != null ? offer.hashCode() : 0; int result = offer != null ? offer.hashCode() : 0;
result = 31 * result + (int) (tradeAmount ^ (tradeAmount >>> 32)); result = 31 * result + (int) (tradeAmount ^ (tradeAmount >>> 32));
result = 31 * result + (int) (tradePrice ^ (tradePrice >>> 32));
result = 31 * result + (takeOfferFeeTxID != null ? takeOfferFeeTxID.hashCode() : 0); result = 31 * result + (takeOfferFeeTxID != null ? takeOfferFeeTxID.hashCode() : 0);
result = 31 * result + (arbitratorNodeAddress != null ? arbitratorNodeAddress.hashCode() : 0); result = 31 * result + (arbitratorNodeAddress != null ? arbitratorNodeAddress.hashCode() : 0);
result = 31 * result + (isBuyerOffererAndSellerTaker ? 1 : 0); result = 31 * result + (isBuyerOffererAndSellerTaker ? 1 : 0);
@ -229,6 +239,7 @@ public final class Contract implements Payload {
return "Contract{" + return "Contract{" +
"\n\toffer=" + offer + "\n\toffer=" + offer +
"\n\ttradeAmount=" + tradeAmount + "\n\ttradeAmount=" + tradeAmount +
"\n\ttradePrice=" + tradePrice +
"\n\ttakeOfferFeeTxID='" + takeOfferFeeTxID + '\'' + "\n\ttakeOfferFeeTxID='" + takeOfferFeeTxID + '\'' +
"\n\tarbitratorAddress=" + arbitratorNodeAddress + "\n\tarbitratorAddress=" + arbitratorNodeAddress +
"\n\tisBuyerOffererAndSellerTaker=" + isBuyerOffererAndSellerTaker + "\n\tisBuyerOffererAndSellerTaker=" + isBuyerOffererAndSellerTaker +

View file

@ -42,8 +42,8 @@ public final class SellerAsTakerTrade extends SellerTrade implements TakerTrade
// Constructor, initialization // Constructor, initialization
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public SellerAsTakerTrade(Offer offer, Coin tradeAmount, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) { public SellerAsTakerTrade(Offer offer, Coin tradeAmount, long tradePrice, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) {
super(offer, tradeAmount, tradingPeerNodeAddress, storage); super(offer, tradeAmount, tradePrice, tradingPeerNodeAddress, storage);
} }
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {

View file

@ -37,8 +37,8 @@ public abstract class SellerTrade extends Trade {
private static final Logger log = LoggerFactory.getLogger(BuyerAsTakerTrade.class); private static final Logger log = LoggerFactory.getLogger(BuyerAsTakerTrade.class);
SellerTrade(Offer offer, Coin tradeAmount, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) { SellerTrade(Offer offer, Coin tradeAmount, long tradePrice, NodeAddress tradingPeerNodeAddress, Storage<? extends TradableList> storage) {
super(offer, tradeAmount, tradingPeerNodeAddress, storage); super(offer, tradeAmount, tradePrice, tradingPeerNodeAddress, storage);
} }
SellerTrade(Offer offer, Storage<? extends TradableList> storage) { SellerTrade(Offer offer, Storage<? extends TradableList> storage) {
@ -69,7 +69,7 @@ public abstract class SellerTrade extends Trade {
public Coin getPayoutAmount() { public Coin getPayoutAmount() {
return FeePolicy.getSecurityDeposit(); return FeePolicy.getSecurityDeposit();
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects // Setter for Mutable objects
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -41,6 +41,7 @@ import javafx.beans.property.*;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence; import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.utils.ExchangeRate;
import org.bitcoinj.utils.Fiat; import org.bitcoinj.utils.Fiat;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -167,6 +168,7 @@ public abstract class Trade implements Tradable, Model {
transient private ObjectProperty<Fiat> tradeVolumeProperty; transient private ObjectProperty<Fiat> tradeVolumeProperty;
@Nullable @Nullable
private String takeOfferFeeTxId; private String takeOfferFeeTxId;
private long tradePrice;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -189,11 +191,12 @@ public abstract class Trade implements Tradable, Model {
} }
// taker // taker
protected Trade(Offer offer, Coin tradeAmount, NodeAddress tradingPeerNodeAddress, protected Trade(Offer offer, Coin tradeAmount, long tradePrice, NodeAddress tradingPeerNodeAddress,
Storage<? extends TradableList> storage) { Storage<? extends TradableList> storage) {
this(offer, storage); this(offer, storage);
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
this.tradePrice = tradePrice;
this.tradingPeerNodeAddress = tradingPeerNodeAddress; this.tradingPeerNodeAddress = tradingPeerNodeAddress;
tradeAmountProperty.set(tradeAmount); tradeAmountProperty.set(tradeAmount);
tradeVolumeProperty.set(getTradeVolume()); tradeVolumeProperty.set(getTradeVolume());
@ -381,8 +384,8 @@ public abstract class Trade implements Tradable, Model {
@Nullable @Nullable
public Fiat getTradeVolume() { public Fiat getTradeVolume() {
if (tradeAmount != null) if (tradeAmount != null && getTradePrice() != null)
return offer.getVolumeByAmount(tradeAmount); return new ExchangeRate(getTradePrice()).coinToFiat(tradeAmount);
else else
return null; return null;
} }
@ -452,6 +455,14 @@ public abstract class Trade implements Tradable, Model {
tradeVolumeProperty.set(getTradeVolume()); tradeVolumeProperty.set(getTradeVolume());
} }
public void setTradePrice(long tradePrice) {
this.tradePrice = tradePrice;
}
public Fiat getTradePrice() {
return Fiat.valueOf(offer.getCurrencyCode(), tradePrice);
}
@Nullable @Nullable
public Coin getTradeAmount() { public Coin getTradeAmount() {
return tradeAmount; return tradeAmount;

View file

@ -113,7 +113,7 @@ public class TradeManager {
tradableListStorage = new Storage<>(storageDir); tradableListStorage = new Storage<>(storageDir);
trades = new TradableList<>(tradableListStorage, "PendingTrades"); trades = new TradableList<>(tradableListStorage, "PendingTrades");
trades.forEach(e -> e.getOffer().setPriceFeed(priceFeed)); trades.forEach(e -> e.getOffer().setPriceFeed(priceFeed));
p2PService.addDecryptedDirectMessageListener(new DecryptedDirectMessageListener() { p2PService.addDecryptedDirectMessageListener(new DecryptedDirectMessageListener() {
@Override @Override
public void onDirectMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey, NodeAddress peerNodeAddress) { public void onDirectMessage(DecryptedMsgWithPubKey decryptedMsgWithPubKey, NodeAddress peerNodeAddress) {
@ -264,6 +264,7 @@ public class TradeManager {
// First we check if offer is still available then we create the trade with the protocol // First we check if offer is still available then we create the trade with the protocol
public void onTakeOffer(Coin amount, public void onTakeOffer(Coin amount,
long tradePrice,
Coin fundsNeededForTrade, Coin fundsNeededForTrade,
Offer offer, Offer offer,
String paymentAccountId, String paymentAccountId,
@ -273,11 +274,12 @@ public class TradeManager {
offer.checkOfferAvailability(model, offer.checkOfferAvailability(model,
() -> { () -> {
if (offer.getState() == Offer.State.AVAILABLE) if (offer.getState() == Offer.State.AVAILABLE)
createTrade(amount, fundsNeededForTrade, offer, paymentAccountId, useSavingsWallet, model, tradeResultHandler); createTrade(amount, tradePrice, fundsNeededForTrade, offer, paymentAccountId, useSavingsWallet, model, tradeResultHandler);
}); });
} }
private void createTrade(Coin amount, private void createTrade(Coin amount,
long tradePrice,
Coin fundsNeededForTrade, Coin fundsNeededForTrade,
Offer offer, Offer offer,
String paymentAccountId, String paymentAccountId,
@ -286,9 +288,9 @@ public class TradeManager {
TradeResultHandler tradeResultHandler) { TradeResultHandler tradeResultHandler) {
Trade trade; Trade trade;
if (offer.getDirection() == Offer.Direction.BUY) if (offer.getDirection() == Offer.Direction.BUY)
trade = new SellerAsTakerTrade(offer, amount, model.getPeerNodeAddress(), tradableListStorage); trade = new SellerAsTakerTrade(offer, amount, tradePrice, model.getPeerNodeAddress(), tradableListStorage);
else else
trade = new BuyerAsTakerTrade(offer, amount, model.getPeerNodeAddress(), tradableListStorage); trade = new BuyerAsTakerTrade(offer, amount, tradePrice, model.getPeerNodeAddress(), tradableListStorage);
trade.setTakerPaymentAccountId(paymentAccountId); trade.setTakerPaymentAccountId(paymentAccountId);

View file

@ -229,7 +229,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
public Fiat getVolumeByAmount(Coin amount) { public Fiat getVolumeByAmount(Coin amount) {
if (fiatPrice != 0 && amount != null && !amount.isZero()) if (fiatPrice != 0 && amount != null && !amount.isZero())
return new ExchangeRate(Fiat.valueOf(currencyCode, fiatPrice)).coinToFiat(amount); return new ExchangeRate(getPrice()).coinToFiat(amount);
else else
return null; return null;
} }
@ -335,6 +335,13 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
double marketPriceAsDouble = marketPrice.getPrice(priceFeedType); double marketPriceAsDouble = marketPrice.getPrice(priceFeedType);
double factor = direction == Offer.Direction.BUY ? 1 - marketPriceMargin : 1 + marketPriceMargin; double factor = direction == Offer.Direction.BUY ? 1 - marketPriceMargin : 1 + marketPriceMargin;
double targetPrice = marketPriceAsDouble * factor; double targetPrice = marketPriceAsDouble * factor;
// round
long factor1 = (long) Math.pow(10, 2);
targetPrice = targetPrice * factor1;
long tmp = Math.round(targetPrice);
targetPrice = (double) tmp / factor1;
try { try {
return Fiat.parseFiat(currencyCode, String.valueOf(targetPrice)); return Fiat.parseFiat(currencyCode, String.valueOf(targetPrice));
} catch (Exception e) { } catch (Exception e) {

View file

@ -35,6 +35,7 @@ public final class PayDepositRequest extends TradeMessage implements MailboxMess
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION; private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
public final long tradeAmount; public final long tradeAmount;
public final long tradePrice;
public final byte[] takerMultiSigPubKey; public final byte[] takerMultiSigPubKey;
public final ArrayList<RawTransactionInput> rawTransactionInputs; public final ArrayList<RawTransactionInput> rawTransactionInputs;
public final long changeOutputValue; public final long changeOutputValue;
@ -52,6 +53,7 @@ public final class PayDepositRequest extends TradeMessage implements MailboxMess
public PayDepositRequest(NodeAddress senderNodeAddress, public PayDepositRequest(NodeAddress senderNodeAddress,
String tradeId, String tradeId,
long tradeAmount, long tradeAmount,
long tradePrice,
ArrayList<RawTransactionInput> rawTransactionInputs, ArrayList<RawTransactionInput> rawTransactionInputs,
long changeOutputValue, long changeOutputValue,
String changeOutputAddress, String changeOutputAddress,
@ -66,6 +68,7 @@ public final class PayDepositRequest extends TradeMessage implements MailboxMess
super(tradeId); super(tradeId);
this.senderNodeAddress = senderNodeAddress; this.senderNodeAddress = senderNodeAddress;
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
this.tradePrice = tradePrice;
this.rawTransactionInputs = rawTransactionInputs; this.rawTransactionInputs = rawTransactionInputs;
this.changeOutputValue = changeOutputValue; this.changeOutputValue = changeOutputValue;
this.changeOutputAddress = changeOutputAddress; this.changeOutputAddress = changeOutputAddress;

View file

@ -60,6 +60,7 @@ public class CreateAndSignContract extends TradeTask {
Contract contract = new Contract( Contract contract = new Contract(
processModel.getOffer(), processModel.getOffer(),
trade.getTradeAmount(), trade.getTradeAmount(),
trade.getTradePrice(),
trade.getTakeOfferFeeTxId(), trade.getTakeOfferFeeTxId(),
buyerNodeAddress, buyerNodeAddress,
sellerNodeAddress, sellerNodeAddress,

View file

@ -77,13 +77,14 @@ public class ProcessPayDepositRequest extends TradeTask {
failed("acceptedArbitratorNames size must be at least 1"); failed("acceptedArbitratorNames size must be at least 1");
trade.setArbitratorNodeAddress(checkNotNull(payDepositRequest.arbitratorNodeAddress)); trade.setArbitratorNodeAddress(checkNotNull(payDepositRequest.arbitratorNodeAddress));
checkArgument(payDepositRequest.tradeAmount > 0); checkArgument(payDepositRequest.tradeAmount > 0);
trade.setTradePrice(payDepositRequest.tradePrice);
trade.setTradeAmount(Coin.valueOf(payDepositRequest.tradeAmount)); trade.setTradeAmount(Coin.valueOf(payDepositRequest.tradeAmount));
// update to the latest peer address of our peer if the payDepositRequest is correct // update to the latest peer address of our peer if the payDepositRequest is correct
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress()); trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
removeMailboxMessageAfterProcessing(); removeMailboxMessageAfterProcessing();
complete(); complete();
} catch (Throwable t) { } catch (Throwable t) {
failed(t); failed(t);

View file

@ -49,6 +49,7 @@ public class SendPayDepositRequest extends TradeTask {
processModel.getMyAddress(), processModel.getMyAddress(),
processModel.getId(), processModel.getId(),
trade.getTradeAmount().value, trade.getTradeAmount().value,
trade.getTradePrice().value,
processModel.getRawTransactionInputs(), processModel.getRawTransactionInputs(),
processModel.getChangeOutputValue(), processModel.getChangeOutputValue(),
processModel.getChangeOutputAddress(), processModel.getChangeOutputAddress(),

View file

@ -61,6 +61,7 @@ public class VerifyAndSignContract extends TradeTask {
Contract contract = new Contract( Contract contract = new Contract(
processModel.getOffer(), processModel.getOffer(),
trade.getTradeAmount(), trade.getTradeAmount(),
trade.getTradePrice(),
trade.getTakeOfferFeeTxId(), trade.getTakeOfferFeeTxId(),
buyerNodeAddress, buyerNodeAddress,
sellerNodeAddress, sellerNodeAddress,

View file

@ -93,14 +93,12 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private TextField currencyTextField; private TextField currencyTextField;
private Label directionLabel, amountDescriptionLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, amountBtcLabel, priceCurrencyLabel, private Label directionLabel, amountDescriptionLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, amountBtcLabel, priceCurrencyLabel,
volumeCurrencyLabel, minAmountBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, currencyTextFieldLabel, volumeCurrencyLabel, minAmountBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, currencyTextFieldLabel,
currencyComboBoxLabel, spinnerInfoLabel; currencyComboBoxLabel, spinnerInfoLabel, priceAsPercentageLabel;
private TextFieldWithCopyIcon totalToPayTextField; private TextFieldWithCopyIcon totalToPayTextField;
private ComboBox<PaymentAccount> paymentAccountsComboBox; private ComboBox<PaymentAccount> paymentAccountsComboBox;
private ComboBox<TradeCurrency> currencyComboBox; private ComboBox<TradeCurrency> currencyComboBox;
private PopOver totalToPayInfoPopover; private PopOver totalToPayInfoPopover;
private Label priceAsPercentageLabel; private ToggleButton fixedPriceButton, percentagePriceButton;
private ToggleButton fixedPriceButton;
private ToggleButton percentagePriceButton;
private OfferView.CloseHandler closeHandler; private OfferView.CloseHandler closeHandler;

View file

@ -576,8 +576,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
long shiftDivisor = checkedPow(10, priceAsFiat.smallestUnitExponent()); long shiftDivisor = checkedPow(10, priceAsFiat.smallestUnitExponent());
double offerPrice = ((double) priceAsFiat.longValue()) / ((double) shiftDivisor); double offerPrice = ((double) priceAsFiat.longValue()) / ((double) shiftDivisor);
double percentage = Math.abs(1 - (offerPrice / marketPriceAsDouble)); double percentage = Math.abs(1 - (offerPrice / marketPriceAsDouble));
percentage = formatter.roundDouble(percentage, 2);
if (marketPriceAsDouble != 0 && percentage > preferences.getMaxPriceDistanceInPercent()) { if (marketPriceAsDouble != 0 && percentage > preferences.getMaxPriceDistanceInPercent()) {
displayPriceOutofRangePopup(); displayPriceOutOfRangePopup();
return false; return false;
} else { } else {
return true; return true;
@ -587,7 +588,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
} }
} }
private void displayPriceOutofRangePopup() { private void displayPriceOutOfRangePopup() {
Popup popup = new Popup(); Popup popup = new Popup();
popup.warning("The price you have entered is outside the max. allowed deviation from the market price.\n" + popup.warning("The price you have entered is outside the max. allowed deviation from the market price.\n" +
"The max. allowed deviation is " + "The max. allowed deviation is " +

View file

@ -92,6 +92,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
boolean useSavingsWallet; boolean useSavingsWallet;
Coin totalAvailableBalance; Coin totalAvailableBalance;
private Notification walletFundedNotification; private Notification walletFundedNotification;
Fiat tradePrice;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -158,6 +159,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
// called before activate // called before activate
void initWithData(Offer offer) { void initWithData(Offer offer) {
this.offer = offer; this.offer = offer;
tradePrice = offer.getPrice();
addressEntry = walletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.OFFER_FUNDING); addressEntry = walletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.OFFER_FUNDING);
checkNotNull(addressEntry, "addressEntry must not be null"); checkNotNull(addressEntry, "addressEntry must not be null");
@ -227,6 +229,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
// have it persisted as well. // have it persisted as well.
void onTakeOffer(TradeResultHandler tradeResultHandler) { void onTakeOffer(TradeResultHandler tradeResultHandler) {
tradeManager.onTakeOffer(amountAsCoin.get(), tradeManager.onTakeOffer(amountAsCoin.get(),
tradePrice.getValue(),
totalToPayAsCoin.get().subtract(takerFeeAsCoin), totalToPayAsCoin.get().subtract(takerFeeAsCoin),
offer, offer,
paymentAccount.getId(), paymentAccount.getId(),
@ -308,7 +311,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
if (offer != null && if (offer != null &&
amountAsCoin.get() != null && amountAsCoin.get() != null &&
!amountAsCoin.get().isZero()) { !amountAsCoin.get().isZero()) {
volumeAsFiat.set(new ExchangeRate(offer.getPrice()).coinToFiat(amountAsCoin.get())); volumeAsFiat.set(new ExchangeRate(tradePrice).coinToFiat(amountAsCoin.get()));
updateBalance(); updateBalance();
} }

View file

@ -90,9 +90,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private TitledGroupBg payFundsPane; private TitledGroupBg payFundsPane;
private Button nextButton, cancelButton1, cancelButton2, fundFromSavingsWalletButton, fundFromExternalWalletButton, takeOfferButton; private Button nextButton, cancelButton1, cancelButton2, fundFromSavingsWalletButton, fundFromExternalWalletButton, takeOfferButton;
private InputTextField amountTextField; private InputTextField amountTextField;
private TextField paymentMethodTextField, currencyTextField, priceTextField, volumeTextField, amountRangeTextField; private TextField paymentMethodTextField, currencyTextField, priceTextField, priceAsPercentageTextField, volumeTextField, amountRangeTextField;
private Label directionLabel, amountDescriptionLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, private Label directionLabel, amountDescriptionLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel,
amountBtcLabel, priceCurrencyLabel, amountBtcLabel, priceCurrencyLabel, priceAsPercentageLabel,
volumeCurrencyLabel, amountRangeBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, spinnerInfoLabel, offerAvailabilitySpinnerLabel; volumeCurrencyLabel, amountRangeBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, spinnerInfoLabel, offerAvailabilitySpinnerLabel;
private TextFieldWithCopyIcon totalToPayTextField; private TextFieldWithCopyIcon totalToPayTextField;
private PopOver totalToPayInfoPopover; private PopOver totalToPayInfoPopover;
@ -228,6 +228,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
amountDescriptionLabel.setText(model.getAmountDescription()); amountDescriptionLabel.setText(model.getAmountDescription());
amountRangeTextField.setText(model.getAmountRange()); amountRangeTextField.setText(model.getAmountRange());
priceTextField.setText(model.getPrice()); priceTextField.setText(model.getPrice());
priceAsPercentageTextField.setText(model.marketPriceMargin);
addressTextField.setPaymentLabel(model.getPaymentLabel()); addressTextField.setPaymentLabel(model.getPaymentLabel());
addressTextField.setAddress(model.dataModel.getAddressEntry().getAddressString()); addressTextField.setAddress(model.dataModel.getAddressEntry().getAddressString());
} }
@ -269,7 +270,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
offerDetailsWindow.hide(); offerDetailsWindow.hide();
offerDetailsWindowDisplayed = false; offerDetailsWindowDisplayed = false;
}) })
).show(model.getOffer(), model.dataModel.amountAsCoin.get()); ).show(model.getOffer(), model.dataModel.amountAsCoin.get(), model.dataModel.tradePrice);
offerDetailsWindowDisplayed = true; offerDetailsWindowDisplayed = true;
} else { } else {
new Popup().warning("You have no arbitrator selected.\n" + new Popup().warning("You have no arbitrator selected.\n" +
@ -285,6 +286,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
amountTextField.setMouseTransparent(true); amountTextField.setMouseTransparent(true);
priceTextField.setMouseTransparent(true); priceTextField.setMouseTransparent(true);
priceAsPercentageTextField.setMouseTransparent(true);
volumeTextField.setMouseTransparent(true); volumeTextField.setMouseTransparent(true);
balanceTextField.setTargetAmount(model.dataModel.totalToPayAsCoin.get()); balanceTextField.setTargetAmount(model.dataModel.totalToPayAsCoin.get());
@ -389,6 +391,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addressTextField.amountAsCoinProperty().bind(model.dataModel.missingCoin); addressTextField.amountAsCoinProperty().bind(model.dataModel.missingCoin);
amountTextField.validationResultProperty().bind(model.amountValidationResult); amountTextField.validationResultProperty().bind(model.amountValidationResult);
priceCurrencyLabel.textProperty().bind(createStringBinding(() -> model.dataModel.getCurrencyCode() + "/" + model.btcCode.get(), model.btcCode)); priceCurrencyLabel.textProperty().bind(createStringBinding(() -> model.dataModel.getCurrencyCode() + "/" + model.btcCode.get(), model.btcCode));
priceAsPercentageLabel.prefWidthProperty().bind(priceCurrencyLabel.widthProperty());
amountRangeBtcLabel.textProperty().bind(model.btcCode); amountRangeBtcLabel.textProperty().bind(model.btcCode);
nextButton.disableProperty().bind(model.isNextButtonDisabled); nextButton.disableProperty().bind(model.isNextButtonDisabled);
@ -414,6 +417,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
addressTextField.amountAsCoinProperty().unbind(); addressTextField.amountAsCoinProperty().unbind();
amountTextField.validationResultProperty().unbind(); amountTextField.validationResultProperty().unbind();
priceCurrencyLabel.textProperty().unbind(); priceCurrencyLabel.textProperty().unbind();
priceAsPercentageLabel.prefWidthProperty().unbind();
amountRangeBtcLabel.textProperty().unbind(); amountRangeBtcLabel.textProperty().unbind();
nextButton.disableProperty().unbind(); nextButton.disableProperty().unbind();
@ -638,8 +642,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
gridPane.getChildren().add(imageVBox); gridPane.getChildren().add(imageVBox);
addAmountPriceFields(); addAmountPriceFields();
addSecondRow();
addAmountRangeBox();
HBox hBox = new HBox(); HBox hBox = new HBox();
hBox.setSpacing(10); hBox.setSpacing(10);
@ -839,18 +842,42 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
gridPane.getChildren().add(hBox); gridPane.getChildren().add(hBox);
} }
private void addAmountRangeBox() { private void addSecondRow() {
Tuple3<HBox, TextField, Label> priceAsPercentageTuple = getValueCurrencyBox();
HBox priceAsPercentageValueCurrencyBox = priceAsPercentageTuple.first;
priceAsPercentageTextField = priceAsPercentageTuple.second;
priceAsPercentageLabel = priceAsPercentageTuple.third;
Tuple2<Label, VBox> priceAsPercentageInputBoxTuple = getTradeInputBox(priceAsPercentageValueCurrencyBox, "Distance in % from market price");
priceAsPercentageInputBoxTuple.first.setPrefWidth(200);
VBox priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
priceAsPercentageTextField.setPromptText("Enter % value");
priceAsPercentageLabel.setText("% dist.");
priceAsPercentageLabel.setStyle("-fx-alignment: center;");
Tuple3<HBox, TextField, Label> amountValueCurrencyBoxTuple = getValueCurrencyBox(); Tuple3<HBox, TextField, Label> amountValueCurrencyBoxTuple = getValueCurrencyBox();
HBox amountValueCurrencyBox = amountValueCurrencyBoxTuple.first; HBox amountValueCurrencyBox = amountValueCurrencyBoxTuple.first;
amountRangeTextField = amountValueCurrencyBoxTuple.second; amountRangeTextField = amountValueCurrencyBoxTuple.second;
amountRangeBtcLabel = amountValueCurrencyBoxTuple.third; amountRangeBtcLabel = amountValueCurrencyBoxTuple.third;
Tuple2<Label, VBox> amountInputBoxTuple = getTradeInputBox(amountValueCurrencyBox, BSResources.get("takeOffer.amountPriceBox.amountRangeDescription")); Tuple2<Label, VBox> amountInputBoxTuple = getTradeInputBox(amountValueCurrencyBox, BSResources.get("takeOffer.amountPriceBox.amountRangeDescription"));
VBox box = amountInputBoxTuple.second;
GridPane.setRowIndex(box, ++gridRow); Label xLabel = new Label("x");
GridPane.setColumnIndex(box, 1); xLabel.setFont(Font.font("Helvetica-Bold", 20));
GridPane.setMargin(box, new Insets(5, 10, 5, 0)); xLabel.setPadding(new Insets(14, 3, 0, 3));
gridPane.getChildren().add(box); xLabel.setVisible(false); // we just use it to get the same layout as the upper row
HBox hBox = new HBox();
hBox.setSpacing(5);
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.getChildren().addAll(amountInputBoxTuple.second, xLabel, priceAsPercentageInputBox);
GridPane.setRowIndex(hBox, ++gridRow);
GridPane.setColumnIndex(hBox, 1);
GridPane.setMargin(hBox, new Insets(5, 10, 5, 0));
GridPane.setColumnSpan(hBox, 2);
gridPane.getChildren().add(hBox);
} }

View file

@ -96,6 +96,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private ConnectionListener connectionListener; private ConnectionListener connectionListener;
// private Subscription isFeeSufficientSubscription; // private Subscription isFeeSufficientSubscription;
private Runnable takeOfferSucceededHandler; private Runnable takeOfferSucceededHandler;
String marketPriceMargin;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -162,7 +163,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
} }
amountRange = formatter.formatCoin(offer.getMinAmount()) + " - " + formatter.formatCoin(offer.getAmount()); amountRange = formatter.formatCoin(offer.getMinAmount()) + " - " + formatter.formatCoin(offer.getAmount());
price = formatter.formatFiat(offer.getPrice()); price = formatter.formatFiat(dataModel.tradePrice);
marketPriceMargin = formatter.formatToPercentWithSymbol(offer.getMarketPriceMargin());
paymentLabel = BSResources.get("takeOffer.fundsBox.paymentLabel", offer.getId()); paymentLabel = BSResources.get("takeOffer.fundsBox.paymentLabel", offer.getId());
checkNotNull(dataModel.getAddressEntry(), "dataModel.getAddressEntry() must not be null"); checkNotNull(dataModel.getAddressEntry(), "dataModel.getAddressEntry() must not be null");

View file

@ -123,7 +123,7 @@ public class ContractWindow extends Overlay<ContractWindow> {
addLabelTextField(gridPane, ++rowIndex, "Offer date:", formatter.formatDateTime(offer.getDate())); addLabelTextField(gridPane, ++rowIndex, "Offer date:", formatter.formatDateTime(offer.getDate()));
addLabelTextField(gridPane, ++rowIndex, "Trade date:", formatter.formatDateTime(dispute.getTradeDate())); addLabelTextField(gridPane, ++rowIndex, "Trade date:", formatter.formatDateTime(dispute.getTradeDate()));
addLabelTextField(gridPane, ++rowIndex, "Trade type:", formatter.getDirectionBothSides(offer.getDirection())); addLabelTextField(gridPane, ++rowIndex, "Trade type:", formatter.getDirectionBothSides(offer.getDirection()));
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode()); addLabelTextField(gridPane, ++rowIndex, "Trade price:", formatter.formatFiat(contract.getTradePrice()) + " " + offer.getCurrencyCode());
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount())); addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount()));
addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer bitcoin address:", addLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, "Buyer bitcoin address:",
contract.getBuyerPayoutAddressString()).second.setMouseTransparent(false); contract.getBuyerPayoutAddressString()).second.setMouseTransparent(false);

View file

@ -47,6 +47,7 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.AddressFormatException;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.ExchangeRate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -232,8 +233,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
} }
addLabelTextField(gridPane, ++rowIndex, "Traders role:", role); addLabelTextField(gridPane, ++rowIndex, "Traders role:", role);
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount())); addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(contract.getTradeAmount()));
addLabelTextField(gridPane, ++rowIndex, "Trade volume:", formatter.formatFiatWithCode(contract.offer.getVolumeByAmount(contract.getTradeAmount()))); addLabelTextField(gridPane, ++rowIndex, "Trade price:", formatter.formatFiatWithCode(contract.getTradePrice()));
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiatWithCode(contract.offer.getPrice())); addLabelTextField(gridPane, ++rowIndex, "Trade volume:", formatter.formatFiatWithCode(new ExchangeRate(contract.getTradePrice()).coinToFiat(contract.getTradeAmount())));
} }
private void addCheckboxes() { private void addCheckboxes() {

View file

@ -41,6 +41,7 @@ import javafx.geometry.Insets;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -61,6 +62,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
private final Navigation navigation; private final Navigation navigation;
private Offer offer; private Offer offer;
private Coin tradeAmount; private Coin tradeAmount;
private Fiat tradePrice;
private Optional<Runnable> placeOfferHandlerOptional = Optional.empty(); private Optional<Runnable> placeOfferHandlerOptional = Optional.empty();
private Optional<Runnable> takeOfferHandlerOptional = Optional.empty(); private Optional<Runnable> takeOfferHandlerOptional = Optional.empty();
private ProgressIndicator spinner; private ProgressIndicator spinner;
@ -80,9 +82,10 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
type = Type.Confirmation; type = Type.Confirmation;
} }
public void show(Offer offer, Coin tradeAmount) { public void show(Offer offer, Coin tradeAmount, Fiat tradePrice) {
this.offer = offer; this.offer = offer;
this.tradeAmount = tradeAmount; this.tradeAmount = tradeAmount;
this.tradePrice = tradePrice;
rowIndex = -1; rowIndex = -1;
width = 900; width = 900;
@ -172,7 +175,10 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
addLabelTextField(gridPane, ++rowIndex, CurrencyUtil.getNameByCode(offer.getCurrencyCode()) + " amount" + fiatDirectionInfo, formatter.formatFiatWithCode(offer.getVolumeByAmount(offer.getAmount()))); addLabelTextField(gridPane, ++rowIndex, CurrencyUtil.getNameByCode(offer.getCurrencyCode()) + " amount" + fiatDirectionInfo, formatter.formatFiatWithCode(offer.getVolumeByAmount(offer.getAmount())));
} }
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC"); if (takeOfferHandlerOptional.isPresent())
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(tradePrice) + " " + offer.getCurrencyCode() + "/" + "BTC");
else
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC");
if (offer.isMyOffer(keyRing) && user.getPaymentAccount(offer.getOffererPaymentAccountId()) != null) if (offer.isMyOffer(keyRing) && user.getPaymentAccount(offer.getOffererPaymentAccountId()) != null)
addLabelTextField(gridPane, ++rowIndex, "Payment account:", user.getPaymentAccount(offer.getOffererPaymentAccountId()).getAccountName()); addLabelTextField(gridPane, ++rowIndex, "Payment account:", user.getPaymentAccount(offer.getOffererPaymentAccountId()).getAccountName());

View file

@ -127,7 +127,7 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
addLabelTextField(gridPane, ++rowIndex, "Bitcoin amount" + btcDirectionInfo, formatter.formatCoinWithCode(trade.getTradeAmount())); addLabelTextField(gridPane, ++rowIndex, "Bitcoin amount" + btcDirectionInfo, formatter.formatCoinWithCode(trade.getTradeAmount()));
addLabelTextField(gridPane, ++rowIndex, CurrencyUtil.getNameByCode(offer.getCurrencyCode()) + " amount" + fiatDirectionInfo, formatter.formatFiatWithCode(trade.getTradeVolume())); addLabelTextField(gridPane, ++rowIndex, CurrencyUtil.getNameByCode(offer.getCurrencyCode()) + " amount" + fiatDirectionInfo, formatter.formatFiatWithCode(trade.getTradeVolume()));
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatPriceWithCode(offer.getPrice())); addLabelTextField(gridPane, ++rowIndex, "Trade price:", formatter.formatPriceWithCode(trade.getTradePrice()));
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId())); addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId()));
// second group // second group

View file

@ -81,7 +81,13 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
tradeIdColumn.setComparator((o1, o2) -> o1.getTradable().getId().compareTo(o2.getTradable().getId())); tradeIdColumn.setComparator((o1, o2) -> o1.getTradable().getId().compareTo(o2.getTradable().getId()));
dateColumn.setComparator((o1, o2) -> o1.getTradable().getDate().compareTo(o2.getTradable().getDate())); dateColumn.setComparator((o1, o2) -> o1.getTradable().getDate().compareTo(o2.getTradable().getDate()));
directionColumn.setComparator((o1, o2) -> o1.getTradable().getOffer().getDirection().compareTo(o2.getTradable().getOffer().getDirection())); directionColumn.setComparator((o1, o2) -> o1.getTradable().getOffer().getDirection().compareTo(o2.getTradable().getOffer().getDirection()));
priceColumn.setComparator((o1, o2) -> o1.getTradable().getOffer().getPrice().compareTo(o2.getTradable().getOffer().getPrice())); priceColumn.setComparator((o1, o2) -> {
Tradable tradable = o1.getTradable();
if (tradable instanceof Trade)
return ((Trade) o1.getTradable()).getTradePrice().compareTo(((Trade) o2.getTradable()).getTradePrice());
else
return o1.getTradable().getOffer().getPrice().compareTo(o2.getTradable().getOffer().getPrice());
});
volumeColumn.setComparator((o1, o2) -> { volumeColumn.setComparator((o1, o2) -> {
if (o1.getTradable() instanceof Trade && o2.getTradable() instanceof Trade) { if (o1.getTradable() instanceof Trade && o2.getTradable() instanceof Trade) {
Fiat tradeVolume1 = ((Trade) o1.getTradable()).getTradeVolume(); Fiat tradeVolume1 = ((Trade) o1.getTradable()).getTradeVolume();

View file

@ -21,6 +21,7 @@ import com.google.inject.Inject;
import io.bitsquare.gui.common.model.ActivatableWithDataModel; import io.bitsquare.gui.common.model.ActivatableWithDataModel;
import io.bitsquare.gui.common.model.ViewModel; import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.Tradable;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import io.bitsquare.trade.offer.OpenOffer; import io.bitsquare.trade.offer.OpenOffer;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@ -54,7 +55,13 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
} }
String getPrice(ClosedTradableListItem item) { String getPrice(ClosedTradableListItem item) {
return (item != null) ? formatter.formatFiat(item.getTradable().getOffer().getPrice()) : ""; if (item == null)
return "";
Tradable tradable = item.getTradable();
if (tradable instanceof Trade)
return formatter.formatFiat(((Trade) tradable).getTradePrice());
else
return formatter.formatFiat(tradable.getOffer().getPrice());
} }
String getVolume(ClosedTradableListItem item) { String getVolume(ClosedTradableListItem item) {

View file

@ -62,7 +62,7 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
tradeIdColumn.setComparator((o1, o2) -> o1.getTrade().getId().compareTo(o2.getTrade().getId())); tradeIdColumn.setComparator((o1, o2) -> o1.getTrade().getId().compareTo(o2.getTrade().getId()));
dateColumn.setComparator((o1, o2) -> o1.getTrade().getDate().compareTo(o2.getTrade().getDate())); dateColumn.setComparator((o1, o2) -> o1.getTrade().getDate().compareTo(o2.getTrade().getDate()));
priceColumn.setComparator((o1, o2) -> o1.getTrade().getOffer().getPrice().compareTo(o2.getTrade().getOffer().getPrice())); priceColumn.setComparator((o1, o2) -> o1.getTrade().getTradePrice().compareTo(o2.getTrade().getTradePrice()));
volumeColumn.setComparator((o1, o2) -> o1.getTrade().getTradeVolume().compareTo(o2.getTrade().getTradeVolume())); volumeColumn.setComparator((o1, o2) -> o1.getTrade().getTradeVolume().compareTo(o2.getTrade().getTradeVolume()));
amountColumn.setComparator((o1, o2) -> o1.getTrade().getTradeAmount().compareTo(o2.getTrade().getTradeAmount())); amountColumn.setComparator((o1, o2) -> o1.getTrade().getTradeAmount().compareTo(o2.getTrade().getTradeAmount()));
stateColumn.setComparator((o1, o2) -> model.getState(o1).compareTo(model.getState(o2))); stateColumn.setComparator((o1, o2) -> model.getState(o1).compareTo(model.getState(o2)));

View file

@ -51,7 +51,7 @@ class FailedTradesViewModel extends ActivatableWithDataModel<FailedTradesDataMod
} }
String getPrice(FailedTradesListItem item) { String getPrice(FailedTradesListItem item) {
return (item != null) ? formatter.formatFiat(item.getTrade().getOffer().getPrice()) : ""; return (item != null) ? formatter.formatFiat(item.getTrade().getTradePrice()) : "";
} }
String getVolume(FailedTradesListItem item) { String getVolume(FailedTradesListItem item) {

View file

@ -46,7 +46,7 @@ public class PendingTradesListItem {
} }
public Fiat getPrice() { public Fiat getPrice() {
return trade.getOffer().getPrice(); return trade.getTradePrice();
} }
} }

View file

@ -380,7 +380,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
public void updateItem(final PendingTradesListItem item, boolean empty) { public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty); super.updateItem(item, empty);
if (item != null && !empty) if (item != null && !empty)
setText(formatter.formatPriceWithCode(item.getTrade().getTradeVolume())); setText(formatter.formatFiatWithCode(item.getTrade().getTradeVolume()));
else else
setText(null); setText(null);
} }

View file

@ -372,7 +372,6 @@ public class BSFormatter {
public double roundDouble(double value, int places) { public double roundDouble(double value, int places) {
if (places < 0) throw new IllegalArgumentException(); if (places < 0) throw new IllegalArgumentException();
long factor = (long) Math.pow(10, places); long factor = (long) Math.pow(10, places);
value = value * factor; value = value * factor;
long tmp = Math.round(value); long tmp = Math.round(value);