Set not used price data to 0 in offer. renamings

This commit is contained in:
Manfred Karrer 2016-04-16 13:35:21 +02:00
parent 1c60bf383c
commit a45f8d7325
6 changed files with 112 additions and 107 deletions

View file

@ -107,15 +107,18 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
private final String id; private final String id;
private final long date; private final long date;
private final long protocolVersion; private final long protocolVersion;
// Price if fixed price is used (usePercentageBasedPrice = false)
// We use 2 type of prices: fixed price or price based on distance from market price
private final boolean useMarketBasedPrice;
// fiatPrice if fixed price is used (usePercentageBasedPrice = false), otherwise 0
private final long fiatPrice; private final long fiatPrice;
// Distance form market price if percentage based price is used (usePercentageBasedPrice = true). // Distance form market price if percentage based price is used (usePercentageBasedPrice = true), otherwise 0.
// E.g. 0.1 -> 10%. Can be negative as well. Depending on direction the marketPriceMargin is above or below the market price. // E.g. 0.1 -> 10%. Can be negative as well. Depending on direction the marketPriceMargin is above or below the market price.
// Positive values is always the usual case where you want a better price as the market. // Positive values is always the usual case where you want a better price as the market.
// E.g. Buy offer with market price 400.- leads to a 360.- price. // E.g. Buy offer with market price 400.- leads to a 360.- price.
// Sell offer with market price 400.- leads to a 440.- price. // Sell offer with market price 400.- leads to a 440.- price.
private final double marketPriceMargin; private final double marketPriceMargin;
private final boolean usePercentageBasedPrice;
private final long amount; private final long amount;
private final long minAmount; private final long minAmount;
private final NodeAddress offererNodeAddress; private final NodeAddress offererNodeAddress;
@ -150,7 +153,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
Direction direction, Direction direction,
long fiatPrice, long fiatPrice,
double marketPriceMargin, double marketPriceMargin,
boolean usePercentageBasedPrice, boolean useMarketBasedPrice,
long amount, long amount,
long minAmount, long minAmount,
String currencyCode, String currencyCode,
@ -168,7 +171,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
this.direction = direction; this.direction = direction;
this.fiatPrice = fiatPrice; this.fiatPrice = fiatPrice;
this.marketPriceMargin = marketPriceMargin; this.marketPriceMargin = marketPriceMargin;
this.usePercentageBasedPrice = usePercentageBasedPrice; this.useMarketBasedPrice = useMarketBasedPrice;
this.amount = amount; this.amount = amount;
this.minAmount = minAmount; this.minAmount = minAmount;
this.currencyCode = currencyCode; this.currencyCode = currencyCode;
@ -234,10 +237,12 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
} }
public Fiat getVolumeByAmount(Coin amount) { public Fiat getVolumeByAmount(Coin amount) {
if (fiatPrice != 0 && amount != null && !amount.isZero()) try {
return new ExchangeRate(getPrice()).coinToFiat(amount); return new ExchangeRate(getPrice()).coinToFiat(amount);
else } catch (Throwable t) {
return null; log.error("getVolumeByAmount failed. Error=" + t.getMessage());
return Fiat.valueOf(currencyCode, 0);
}
} }
public Fiat getOfferVolume() { public Fiat getOfferVolume() {
@ -333,8 +338,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
} }
public Fiat getPrice() { public Fiat getPrice() {
Fiat priceAsFiat = Fiat.valueOf(currencyCode, fiatPrice); if (useMarketBasedPrice) {
if (usePercentageBasedPrice && priceFeed != null) { checkNotNull(priceFeed, "priceFeed must not be null");
MarketPrice marketPrice = priceFeed.getMarketPrice(currencyCode); MarketPrice marketPrice = priceFeed.getMarketPrice(currencyCode);
if (marketPrice != null) { if (marketPrice != null) {
PriceFeed.Type priceFeedType = direction == Direction.BUY ? PriceFeed.Type.ASK : PriceFeed.Type.BID; PriceFeed.Type priceFeedType = direction == Direction.BUY ? PriceFeed.Type.ASK : PriceFeed.Type.BID;
@ -347,22 +352,22 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
targetPrice = targetPrice * factor1; targetPrice = targetPrice * factor1;
long tmp = Math.round(targetPrice); long tmp = Math.round(targetPrice);
targetPrice = (double) tmp / factor1; 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) {
log.warn("Exception at parseToFiat: " + e.toString()); log.error("Exception at getPrice / parseToFiat: " + e.toString() + "\n" +
log.warn("We use the static price."); "We use an inaccessible price to avoid null pointers.\n" +
return priceAsFiat; "That case should never happen.");
return Fiat.valueOf(currencyCode, direction == Direction.BUY ? Long.MIN_VALUE : Long.MAX_VALUE);
} }
} else { } else {
log.warn("We don't have a market price. We use the static price instead."); log.warn("We don't have a market price. We use an inaccessible price to avoid null pointers.\n" +
return priceAsFiat; "That case could only happen if you don't get a price feed.");
return Fiat.valueOf(currencyCode, direction == Direction.BUY ? Long.MIN_VALUE : Long.MAX_VALUE);
} }
} else { } else {
if (priceFeed == null) return Fiat.valueOf(currencyCode, fiatPrice);
log.warn("priceFeed must not be null");
return priceAsFiat;
} }
} }
@ -370,8 +375,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
return marketPriceMargin; return marketPriceMargin;
} }
public boolean getUsePercentageBasedPrice() { public boolean getUseMarketBasedPrice() {
return usePercentageBasedPrice; return useMarketBasedPrice;
} }
public Coin getAmount() { public Coin getAmount() {
@ -454,7 +459,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
if (date != offer.date) return false; if (date != offer.date) return false;
if (fiatPrice != offer.fiatPrice) return false; if (fiatPrice != offer.fiatPrice) return false;
if (Double.compare(offer.marketPriceMargin, marketPriceMargin) != 0) return false; if (Double.compare(offer.marketPriceMargin, marketPriceMargin) != 0) return false;
if (usePercentageBasedPrice != offer.usePercentageBasedPrice) return false; if (useMarketBasedPrice != offer.useMarketBasedPrice) return false;
if (amount != offer.amount) return false; if (amount != offer.amount) return false;
if (minAmount != offer.minAmount) return false; if (minAmount != offer.minAmount) return false;
if (id != null ? !id.equals(offer.id) : offer.id != null) return false; if (id != null ? !id.equals(offer.id) : offer.id != null) return false;
@ -488,7 +493,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
result = 31 * result + (int) (fiatPrice ^ (fiatPrice >>> 32)); result = 31 * result + (int) (fiatPrice ^ (fiatPrice >>> 32));
long temp = Double.doubleToLongBits(marketPriceMargin); long temp = Double.doubleToLongBits(marketPriceMargin);
result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (usePercentageBasedPrice ? 1 : 0); result = 31 * result + (useMarketBasedPrice ? 1 : 0);
result = 31 * result + (int) (amount ^ (amount >>> 32)); result = 31 * result + (int) (amount ^ (amount >>> 32));
result = 31 * result + (int) (minAmount ^ (minAmount >>> 32)); result = 31 * result + (int) (minAmount ^ (minAmount >>> 32));
result = 31 * result + (offererNodeAddress != null ? offererNodeAddress.hashCode() : 0); result = 31 * result + (offererNodeAddress != null ? offererNodeAddress.hashCode() : 0);
@ -513,7 +518,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
"\n\tdate=" + date + "\n\tdate=" + date +
"\n\tfiatPrice=" + fiatPrice + "\n\tfiatPrice=" + fiatPrice +
"\n\tmarketPriceMargin=" + marketPriceMargin + "\n\tmarketPriceMargin=" + marketPriceMargin +
"\n\tusePercentageBasedPrice=" + usePercentageBasedPrice + "\n\tuseMarketBasedPrice=" + useMarketBasedPrice +
"\n\tamount=" + amount + "\n\tamount=" + amount +
"\n\tminAmount=" + minAmount + "\n\tminAmount=" + minAmount +
"\n\toffererAddress=" + offererNodeAddress + "\n\toffererAddress=" + offererNodeAddress +

View file

@ -89,7 +89,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
final StringProperty btcCode = new SimpleStringProperty(); final StringProperty btcCode = new SimpleStringProperty();
final BooleanProperty isWalletFunded = new SimpleBooleanProperty(); final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
final BooleanProperty usePercentageBasedPrice = new SimpleBooleanProperty(); final BooleanProperty useMarketBasedPrice = new SimpleBooleanProperty();
//final BooleanProperty isMainNet = new SimpleBooleanProperty(); //final BooleanProperty isMainNet = new SimpleBooleanProperty();
//final BooleanProperty isFeeFromFundingTxSufficient = new SimpleBooleanProperty(); //final BooleanProperty isFeeFromFundingTxSufficient = new SimpleBooleanProperty();
@ -109,7 +109,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
private Notification walletFundedNotification; private Notification walletFundedNotification;
boolean useSavingsWallet; boolean useSavingsWallet;
Coin totalAvailableBalance; Coin totalAvailableBalance;
private double percentageBasedPrice = 0; private double marketPriceMargin = 0;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -140,7 +140,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades(); networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
securityDepositAsCoin = FeePolicy.getSecurityDeposit(); securityDepositAsCoin = FeePolicy.getSecurityDeposit();
usePercentageBasedPrice.set(preferences.getUsePercentageBasedPrice()); useMarketBasedPrice.set(preferences.getUsePercentageBasedPrice());
balanceListener = new BalanceListener(getAddressEntry().getAddress()) { balanceListener = new BalanceListener(getAddressEntry().getAddress()) {
@Override @Override
@ -256,8 +256,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
Offer createAndGetOffer() { Offer createAndGetOffer() {
long fiatPrice = priceAsFiat.get() != null ? priceAsFiat.get().getValue() : 0L; long fiatPrice = priceAsFiat.get() != null && !useMarketBasedPrice.get() ? priceAsFiat.get().getValue() : 0L;
double marketPriceMarginParam = useMarketBasedPrice.get() ? marketPriceMargin : 0;
long amount = amountAsCoin.get() != null ? amountAsCoin.get().getValue() : 0L; long amount = amountAsCoin.get() != null ? amountAsCoin.get().getValue() : 0L;
long minAmount = minAmountAsCoin.get() != null ? minAmountAsCoin.get().getValue() : 0L; long minAmount = minAmountAsCoin.get() != null ? minAmountAsCoin.get().getValue() : 0L;
@ -289,8 +289,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
keyRing.getPubKeyRing(), keyRing.getPubKeyRing(),
direction, direction,
fiatPrice, fiatPrice,
percentageBasedPrice, marketPriceMarginParam,
usePercentageBasedPrice.get(), useMarketBasedPrice.get(),
amount, amount,
minAmount, minAmount,
tradeCurrencyCode.get(), tradeCurrencyCode.get(),
@ -386,9 +386,9 @@ class CreateOfferDataModel extends ActivatableDataModel {
return user.getAcceptedArbitrators().size() > 0; return user.getAcceptedArbitrators().size() > 0;
} }
public void setUsePercentageBasedPrice(boolean usePercentageBasedPrice) { public void setUseMarketBasedPrice(boolean useMarketBasedPrice) {
this.usePercentageBasedPrice.set(usePercentageBasedPrice); this.useMarketBasedPrice.set(useMarketBasedPrice);
preferences.setUsePercentageBasedPrice(usePercentageBasedPrice); preferences.setUsePercentageBasedPrice(useMarketBasedPrice);
} }
/*boolean isFeeFromFundingTxSufficient() { /*boolean isFeeFromFundingTxSufficient() {
@ -498,11 +498,11 @@ class CreateOfferDataModel extends ActivatableDataModel {
walletService.swapTradeEntryToAvailableEntry(offerId, AddressEntry.Context.RESERVED_FOR_TRADE); walletService.swapTradeEntryToAvailableEntry(offerId, AddressEntry.Context.RESERVED_FOR_TRADE);
} }
double getPercentageBasedPrice() { double getMarketPriceMargin() {
return percentageBasedPrice; return marketPriceMargin;
} }
void setPercentageBasedPrice(double percentageBasedPrice) { void setMarketPriceMargin(double marketPriceMargin) {
this.percentageBasedPrice = percentageBasedPrice; this.marketPriceMargin = marketPriceMargin;
} }
} }

View file

@ -91,17 +91,17 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private BalanceTextField balanceTextField; private BalanceTextField balanceTextField;
private TitledGroupBg payFundsPane; private TitledGroupBg payFundsPane;
private ProgressIndicator spinner; private ProgressIndicator spinner;
private Button nextButton, cancelButton1, cancelButton2, fundFromSavingsWalletButton, fundFromExternalWalletButton, placeOfferButton, usePercentageBasedPriceButton; private Button nextButton, cancelButton1, cancelButton2, fundFromSavingsWalletButton, fundFromExternalWalletButton, placeOfferButton;
private InputTextField amountTextField, minAmountTextField, priceTextField, priceAsPercentageTextField, volumeTextField; private InputTextField amountTextField, minAmountTextField, fixedPriceTextField, marketBasedPriceTextField, volumeTextField;
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, priceAsPercentageLabel; currencyComboBoxLabel, spinnerInfoLabel, marketBasedPriceLabel;
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 ToggleButton fixedPriceButton, percentagePriceButton; private ToggleButton fixedPriceButton, useMarketBasedPriceButton;
private OfferView.CloseHandler closeHandler; private OfferView.CloseHandler closeHandler;
@ -180,8 +180,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
if (spinner != null && spinner.isVisible()) if (spinner != null && spinner.isVisible())
spinner.setProgress(-1); spinner.setProgress(-1);
percentagePriceButton.setSelected(model.dataModel.usePercentageBasedPrice.get()); useMarketBasedPriceButton.setSelected(model.dataModel.useMarketBasedPrice.get());
fixedPriceButton.setSelected(!model.dataModel.usePercentageBasedPrice.get()); fixedPriceButton.setSelected(!model.dataModel.useMarketBasedPrice.get());
directionLabel.setText(model.getDirectionLabel()); directionLabel.setText(model.getDirectionLabel());
amountDescriptionLabel.setText(model.getAmountDescription()); amountDescriptionLabel.setText(model.getAmountDescription());
@ -413,19 +413,19 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private void addBindings() { private void addBindings() {
amountBtcLabel.textProperty().bind(model.btcCode); amountBtcLabel.textProperty().bind(model.btcCode);
priceCurrencyLabel.textProperty().bind(createStringBinding(() -> model.tradeCurrencyCode.get() + "/" + model.btcCode.get(), model.btcCode, model.tradeCurrencyCode)); priceCurrencyLabel.textProperty().bind(createStringBinding(() -> model.tradeCurrencyCode.get() + "/" + model.btcCode.get(), model.btcCode, model.tradeCurrencyCode));
priceTextField.disableProperty().bind(model.dataModel.usePercentageBasedPrice); fixedPriceTextField.disableProperty().bind(model.dataModel.useMarketBasedPrice);
priceCurrencyLabel.disableProperty().bind(model.dataModel.usePercentageBasedPrice); priceCurrencyLabel.disableProperty().bind(model.dataModel.useMarketBasedPrice);
priceAsPercentageTextField.disableProperty().bind(model.dataModel.usePercentageBasedPrice.not()); marketBasedPriceTextField.disableProperty().bind(model.dataModel.useMarketBasedPrice.not());
priceAsPercentageLabel.disableProperty().bind(model.dataModel.usePercentageBasedPrice.not()); marketBasedPriceLabel.disableProperty().bind(model.dataModel.useMarketBasedPrice.not());
priceAsPercentageLabel.prefWidthProperty().bind(priceCurrencyLabel.widthProperty()); marketBasedPriceLabel.prefWidthProperty().bind(priceCurrencyLabel.widthProperty());
volumeCurrencyLabel.textProperty().bind(model.tradeCurrencyCode); volumeCurrencyLabel.textProperty().bind(model.tradeCurrencyCode);
minAmountBtcLabel.textProperty().bind(model.btcCode); minAmountBtcLabel.textProperty().bind(model.btcCode);
priceDescriptionLabel.textProperty().bind(createStringBinding(() -> BSResources.get("createOffer.amountPriceBox.priceDescription", model.tradeCurrencyCode.get()), model.tradeCurrencyCode)); priceDescriptionLabel.textProperty().bind(createStringBinding(() -> BSResources.get("createOffer.amountPriceBox.priceDescription", model.tradeCurrencyCode.get()), model.tradeCurrencyCode));
volumeDescriptionLabel.textProperty().bind(createStringBinding(model.volumeDescriptionLabel::get, model.tradeCurrencyCode, model.volumeDescriptionLabel)); volumeDescriptionLabel.textProperty().bind(createStringBinding(model.volumeDescriptionLabel::get, model.tradeCurrencyCode, model.volumeDescriptionLabel));
amountTextField.textProperty().bindBidirectional(model.amount); amountTextField.textProperty().bindBidirectional(model.amount);
minAmountTextField.textProperty().bindBidirectional(model.minAmount); minAmountTextField.textProperty().bindBidirectional(model.minAmount);
priceTextField.textProperty().bindBidirectional(model.price); fixedPriceTextField.textProperty().bindBidirectional(model.price);
priceAsPercentageTextField.textProperty().bindBidirectional(model.priceAsPercentage); marketBasedPriceTextField.textProperty().bindBidirectional(model.priceAsPercentage);
volumeTextField.textProperty().bindBidirectional(model.volume); volumeTextField.textProperty().bindBidirectional(model.volume);
volumeTextField.promptTextProperty().bind(model.volumePromptLabel); volumeTextField.promptTextProperty().bind(model.volumePromptLabel);
totalToPayTextField.textProperty().bind(model.totalToPay); totalToPayTextField.textProperty().bind(model.totalToPay);
@ -434,7 +434,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
// Validation // Validation
amountTextField.validationResultProperty().bind(model.amountValidationResult); amountTextField.validationResultProperty().bind(model.amountValidationResult);
minAmountTextField.validationResultProperty().bind(model.minAmountValidationResult); minAmountTextField.validationResultProperty().bind(model.minAmountValidationResult);
priceTextField.validationResultProperty().bind(model.priceValidationResult); fixedPriceTextField.validationResultProperty().bind(model.priceValidationResult);
volumeTextField.validationResultProperty().bind(model.volumeValidationResult); volumeTextField.validationResultProperty().bind(model.volumeValidationResult);
// funding // funding
@ -464,19 +464,19 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private void removeBindings() { private void removeBindings() {
amountBtcLabel.textProperty().unbind(); amountBtcLabel.textProperty().unbind();
priceCurrencyLabel.textProperty().unbind(); priceCurrencyLabel.textProperty().unbind();
priceTextField.disableProperty().unbind(); fixedPriceTextField.disableProperty().unbind();
priceCurrencyLabel.disableProperty().unbind(); priceCurrencyLabel.disableProperty().unbind();
priceAsPercentageTextField.disableProperty().unbind(); marketBasedPriceTextField.disableProperty().unbind();
priceAsPercentageLabel.disableProperty().unbind(); marketBasedPriceLabel.disableProperty().unbind();
volumeCurrencyLabel.textProperty().unbind(); volumeCurrencyLabel.textProperty().unbind();
minAmountBtcLabel.textProperty().unbind(); minAmountBtcLabel.textProperty().unbind();
priceDescriptionLabel.textProperty().unbind(); priceDescriptionLabel.textProperty().unbind();
volumeDescriptionLabel.textProperty().unbind(); volumeDescriptionLabel.textProperty().unbind();
amountTextField.textProperty().unbindBidirectional(model.amount); amountTextField.textProperty().unbindBidirectional(model.amount);
minAmountTextField.textProperty().unbindBidirectional(model.minAmount); minAmountTextField.textProperty().unbindBidirectional(model.minAmount);
priceTextField.textProperty().unbindBidirectional(model.price); fixedPriceTextField.textProperty().unbindBidirectional(model.price);
priceAsPercentageTextField.textProperty().unbindBidirectional(model.priceAsPercentage); marketBasedPriceTextField.textProperty().unbindBidirectional(model.priceAsPercentage);
priceAsPercentageLabel.prefWidthProperty().unbind(); marketBasedPriceLabel.prefWidthProperty().unbind();
volumeTextField.textProperty().unbindBidirectional(model.volume); volumeTextField.textProperty().unbindBidirectional(model.volume);
volumeTextField.promptTextProperty().unbindBidirectional(model.volume); volumeTextField.promptTextProperty().unbindBidirectional(model.volume);
totalToPayTextField.textProperty().unbind(); totalToPayTextField.textProperty().unbind();
@ -485,7 +485,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
// Validation // Validation
amountTextField.validationResultProperty().unbind(); amountTextField.validationResultProperty().unbind();
minAmountTextField.validationResultProperty().unbind(); minAmountTextField.validationResultProperty().unbind();
priceTextField.validationResultProperty().unbind(); fixedPriceTextField.validationResultProperty().unbind();
volumeTextField.validationResultProperty().unbind(); volumeTextField.validationResultProperty().unbind();
// funding // funding
@ -539,12 +539,12 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
minAmountTextField.setText(model.minAmount.get()); minAmountTextField.setText(model.minAmount.get());
}; };
priceFocusedListener = (o, oldValue, newValue) -> { priceFocusedListener = (o, oldValue, newValue) -> {
model.onFocusOutPriceTextField(oldValue, newValue, priceTextField.getText()); model.onFocusOutPriceTextField(oldValue, newValue, fixedPriceTextField.getText());
priceTextField.setText(model.price.get()); fixedPriceTextField.setText(model.price.get());
}; };
priceAsPercentageFocusedListener = (o, oldValue, newValue) -> { priceAsPercentageFocusedListener = (o, oldValue, newValue) -> {
model.onFocusOutPriceAsPercentageTextField(oldValue, newValue, priceAsPercentageTextField.getText()); model.onFocusOutPriceAsPercentageTextField(oldValue, newValue, marketBasedPriceTextField.getText());
priceAsPercentageTextField.setText(model.priceAsPercentage.get()); marketBasedPriceTextField.setText(model.priceAsPercentage.get());
}; };
volumeFocusedListener = (o, oldValue, newValue) -> { volumeFocusedListener = (o, oldValue, newValue) -> {
model.onFocusOutVolumeTextField(oldValue, newValue, volumeTextField.getText()); model.onFocusOutVolumeTextField(oldValue, newValue, volumeTextField.getText());
@ -604,8 +604,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
currencyComboBoxSelectionHandler = e -> onCurrencyComboBoxSelected(); currencyComboBoxSelectionHandler = e -> onCurrencyComboBoxSelected();
tradeCurrencyCodeListener = (observable, oldValue, newValue) -> { tradeCurrencyCodeListener = (observable, oldValue, newValue) -> {
priceTextField.clear(); fixedPriceTextField.clear();
priceAsPercentageTextField.clear(); marketBasedPriceTextField.clear();
volumeTextField.clear(); volumeTextField.clear();
}; };
@ -643,8 +643,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
// focus out // focus out
amountTextField.focusedProperty().addListener(amountFocusedListener); amountTextField.focusedProperty().addListener(amountFocusedListener);
minAmountTextField.focusedProperty().addListener(minAmountFocusedListener); minAmountTextField.focusedProperty().addListener(minAmountFocusedListener);
priceTextField.focusedProperty().addListener(priceFocusedListener); fixedPriceTextField.focusedProperty().addListener(priceFocusedListener);
priceAsPercentageTextField.focusedProperty().addListener(priceAsPercentageFocusedListener); marketBasedPriceTextField.focusedProperty().addListener(priceAsPercentageFocusedListener);
volumeTextField.focusedProperty().addListener(volumeFocusedListener); volumeTextField.focusedProperty().addListener(volumeFocusedListener);
// warnings // warnings
@ -667,8 +667,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
// focus out // focus out
amountTextField.focusedProperty().removeListener(amountFocusedListener); amountTextField.focusedProperty().removeListener(amountFocusedListener);
minAmountTextField.focusedProperty().removeListener(minAmountFocusedListener); minAmountTextField.focusedProperty().removeListener(minAmountFocusedListener);
priceTextField.focusedProperty().removeListener(priceFocusedListener); fixedPriceTextField.focusedProperty().removeListener(priceFocusedListener);
priceAsPercentageTextField.focusedProperty().removeListener(priceAsPercentageFocusedListener); marketBasedPriceTextField.focusedProperty().removeListener(priceAsPercentageFocusedListener);
volumeTextField.focusedProperty().removeListener(volumeFocusedListener); volumeTextField.focusedProperty().removeListener(volumeFocusedListener);
// warnings // warnings
@ -934,8 +934,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
// price as fiat // price as fiat
Tuple3<HBox, InputTextField, Label> priceValueCurrencyBoxTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt")); Tuple3<HBox, InputTextField, Label> priceValueCurrencyBoxTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt"));
HBox priceValueCurrencyBox = priceValueCurrencyBoxTuple.first; HBox priceValueCurrencyBox = priceValueCurrencyBoxTuple.first;
priceTextField = priceValueCurrencyBoxTuple.second; fixedPriceTextField = priceValueCurrencyBoxTuple.second;
editOfferElements.add(priceTextField); editOfferElements.add(fixedPriceTextField);
priceCurrencyLabel = priceValueCurrencyBoxTuple.third; priceCurrencyLabel = priceValueCurrencyBoxTuple.third;
editOfferElements.add(priceCurrencyLabel); editOfferElements.add(priceCurrencyLabel);
Tuple2<Label, VBox> priceInputBoxTuple = getTradeInputBox(priceValueCurrencyBox, BSResources.get("createOffer.amountPriceBox.priceDescription")); Tuple2<Label, VBox> priceInputBoxTuple = getTradeInputBox(priceValueCurrencyBox, BSResources.get("createOffer.amountPriceBox.priceDescription"));
@ -950,22 +950,22 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
fixedPriceButton.setId("toggle-price-left"); fixedPriceButton.setId("toggle-price-left");
fixedPriceButton.setToggleGroup(toggleGroup); fixedPriceButton.setToggleGroup(toggleGroup);
fixedPriceButton.selectedProperty().addListener((ov, oldValue, newValue) -> { fixedPriceButton.selectedProperty().addListener((ov, oldValue, newValue) -> {
model.dataModel.setUsePercentageBasedPrice(!newValue); model.dataModel.setUseMarketBasedPrice(!newValue);
percentagePriceButton.setSelected(!newValue); useMarketBasedPriceButton.setSelected(!newValue);
}); });
percentagePriceButton = new ToggleButton("Percentage"); useMarketBasedPriceButton = new ToggleButton("Percentage");
editOfferElements.add(percentagePriceButton); editOfferElements.add(useMarketBasedPriceButton);
percentagePriceButton.setId("toggle-price-right"); useMarketBasedPriceButton.setId("toggle-price-right");
percentagePriceButton.setToggleGroup(toggleGroup); useMarketBasedPriceButton.setToggleGroup(toggleGroup);
percentagePriceButton.selectedProperty().addListener((ov, oldValue, newValue) -> { useMarketBasedPriceButton.selectedProperty().addListener((ov, oldValue, newValue) -> {
model.dataModel.setUsePercentageBasedPrice(newValue); model.dataModel.setUseMarketBasedPrice(newValue);
fixedPriceButton.setSelected(!newValue); fixedPriceButton.setSelected(!newValue);
}); });
HBox toggleButtons = new HBox(); HBox toggleButtons = new HBox();
toggleButtons.setPadding(new Insets(18, 0, 0, 0)); toggleButtons.setPadding(new Insets(18, 0, 0, 0));
toggleButtons.getChildren().addAll(fixedPriceButton, percentagePriceButton); toggleButtons.getChildren().addAll(fixedPriceButton, useMarketBasedPriceButton);
// = // =
Label resultLabel = new Label("="); Label resultLabel = new Label("=");
@ -998,18 +998,18 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private void addSecondRow() { private void addSecondRow() {
Tuple3<HBox, InputTextField, Label> priceAsPercentageTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt")); Tuple3<HBox, InputTextField, Label> priceAsPercentageTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt"));
HBox priceAsPercentageValueCurrencyBox = priceAsPercentageTuple.first; HBox priceAsPercentageValueCurrencyBox = priceAsPercentageTuple.first;
priceAsPercentageTextField = priceAsPercentageTuple.second; marketBasedPriceTextField = priceAsPercentageTuple.second;
editOfferElements.add(priceAsPercentageTextField); editOfferElements.add(marketBasedPriceTextField);
priceAsPercentageLabel = priceAsPercentageTuple.third; marketBasedPriceLabel = priceAsPercentageTuple.third;
editOfferElements.add(priceAsPercentageLabel); editOfferElements.add(marketBasedPriceLabel);
Tuple2<Label, VBox> priceAsPercentageInputBoxTuple = getTradeInputBox(priceAsPercentageValueCurrencyBox, "Distance in % from market price"); Tuple2<Label, VBox> priceAsPercentageInputBoxTuple = getTradeInputBox(priceAsPercentageValueCurrencyBox, "Distance in % from market price");
priceAsPercentageInputBoxTuple.first.setPrefWidth(200); priceAsPercentageInputBoxTuple.first.setPrefWidth(200);
VBox priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second; VBox priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
priceAsPercentageTextField.setPromptText("Enter % value"); marketBasedPriceTextField.setPromptText("Enter % value");
priceAsPercentageLabel.setText("%"); marketBasedPriceLabel.setText("%");
priceAsPercentageLabel.setStyle("-fx-alignment: center;"); marketBasedPriceLabel.setStyle("-fx-alignment: center;");
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getValueCurrencyBox(BSResources.get("createOffer.amount.prompt")); Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getValueCurrencyBox(BSResources.get("createOffer.amount.prompt"));
HBox amountValueCurrencyBox = amountValueCurrencyBoxTuple.first; HBox amountValueCurrencyBox = amountValueCurrencyBoxTuple.first;

View file

@ -104,7 +104,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
private ChangeListener<String> amountListener; private ChangeListener<String> amountListener;
private ChangeListener<String> minAmountListener; private ChangeListener<String> minAmountListener;
private ChangeListener<String> priceListener, priceAsPercentageListener; private ChangeListener<String> priceListener, marketPriceMarginListener;
private ChangeListener<String> volumeListener; private ChangeListener<String> volumeListener;
private ChangeListener<Coin> amountAsCoinListener; private ChangeListener<Coin> amountAsCoinListener;
private ChangeListener<Coin> minAmountAsCoinListener; private ChangeListener<Coin> minAmountAsCoinListener;
@ -116,8 +116,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
private Offer offer; private Offer offer;
private Timer timeoutTimer; private Timer timeoutTimer;
private PriceFeed.Type priceFeedType; private PriceFeed.Type priceFeedType;
private boolean priceAsPercentageIsInput; private boolean inputIsMarketBasedPrice;
private ChangeListener<Boolean> usePercentageBasedPriceListener; private ChangeListener<Boolean> useMarketBasedPriceListener;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -240,7 +240,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
calculateVolume(); calculateVolume();
dataModel.calculateTotalToPay(); dataModel.calculateTotalToPay();
if (!priceAsPercentageIsInput) { if (!inputIsMarketBasedPrice) {
MarketPrice marketPrice = priceFeed.getMarketPrice(dataModel.tradeCurrencyCode.get()); MarketPrice marketPrice = priceFeed.getMarketPrice(dataModel.tradeCurrencyCode.get());
if (marketPrice != null) { if (marketPrice != null) {
double marketPriceAsDouble = formatter.roundDouble(marketPrice.getPrice(priceFeedType), 2); double marketPriceAsDouble = formatter.roundDouble(marketPrice.getPrice(priceFeedType), 2);
@ -262,13 +262,13 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
} }
updateButtonDisableState(); updateButtonDisableState();
}; };
priceAsPercentageListener = (ov, oldValue, newValue) -> { marketPriceMarginListener = (ov, oldValue, newValue) -> {
if (priceAsPercentageIsInput) { if (inputIsMarketBasedPrice) {
try { try {
if (!newValue.isEmpty() && !newValue.equals("-")) { if (!newValue.isEmpty() && !newValue.equals("-")) {
double marketPriceMargin = formatter.parsePercentStringToDouble(newValue); double marketPriceMargin = formatter.parsePercentStringToDouble(newValue);
if (marketPriceMargin >= 1 || marketPriceMargin <= -1) { if (marketPriceMargin >= 1 || marketPriceMargin <= -1) {
dataModel.setPercentageBasedPrice(0); dataModel.setMarketPriceMargin(0);
UserThread.execute(() -> priceAsPercentage.set("0")); UserThread.execute(() -> priceAsPercentage.set("0"));
new Popup().warning("You cannot set a percentage of 100% or larger. Please enter a percentage number like \"5.4\" for 5.4%") new Popup().warning("You cannot set a percentage of 100% or larger. Please enter a percentage number like \"5.4\" for 5.4%")
.show(); .show();
@ -276,7 +276,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
MarketPrice marketPrice = priceFeed.getMarketPrice(dataModel.tradeCurrencyCode.get()); MarketPrice marketPrice = priceFeed.getMarketPrice(dataModel.tradeCurrencyCode.get());
if (marketPrice != null) { if (marketPrice != null) {
marketPriceMargin = formatter.roundDouble(marketPriceMargin, 4); marketPriceMargin = formatter.roundDouble(marketPriceMargin, 4);
dataModel.setPercentageBasedPrice(marketPriceMargin); dataModel.setMarketPriceMargin(marketPriceMargin);
Offer.Direction direction = dataModel.getDirection(); Offer.Direction direction = dataModel.getDirection();
double marketPriceAsDouble = formatter.roundDouble(marketPrice.getPrice(priceFeedType), 2); double marketPriceAsDouble = formatter.roundDouble(marketPrice.getPrice(priceFeedType), 2);
double factor = direction == Offer.Direction.BUY ? 1 - marketPriceMargin : 1 + marketPriceMargin; double factor = direction == Offer.Direction.BUY ? 1 - marketPriceMargin : 1 + marketPriceMargin;
@ -292,17 +292,17 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
} }
} }
} else { } else {
dataModel.setPercentageBasedPrice(0); dataModel.setMarketPriceMargin(0);
} }
} catch (Throwable t) { } catch (Throwable t) {
dataModel.setPercentageBasedPrice(0); dataModel.setMarketPriceMargin(0);
UserThread.execute(() -> priceAsPercentage.set("0")); UserThread.execute(() -> priceAsPercentage.set("0"));
new Popup().warning("Your input is not a valid number. Please enter a percentage number like \"5.4\" for 5.4%") new Popup().warning("Your input is not a valid number. Please enter a percentage number like \"5.4\" for 5.4%")
.show(); .show();
} }
} }
}; };
usePercentageBasedPriceListener = (observable, oldValue, newValue) -> { useMarketBasedPriceListener = (observable, oldValue, newValue) -> {
if (newValue) if (newValue)
priceValidationResult.set(new InputValidator.ValidationResult(true)); priceValidationResult.set(new InputValidator.ValidationResult(true));
}; };
@ -335,8 +335,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
amount.addListener(amountListener); amount.addListener(amountListener);
minAmount.addListener(minAmountListener); minAmount.addListener(minAmountListener);
price.addListener(priceListener); price.addListener(priceListener);
priceAsPercentage.addListener(priceAsPercentageListener); priceAsPercentage.addListener(marketPriceMarginListener);
dataModel.usePercentageBasedPrice.addListener(usePercentageBasedPriceListener); dataModel.useMarketBasedPrice.addListener(useMarketBasedPriceListener);
volume.addListener(volumeListener); volume.addListener(volumeListener);
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding // Binding with Bindings.createObjectBinding does not work because of bi-directional binding
@ -353,8 +353,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
amount.removeListener(amountListener); amount.removeListener(amountListener);
minAmount.removeListener(minAmountListener); minAmount.removeListener(minAmountListener);
price.removeListener(priceListener); price.removeListener(priceListener);
priceAsPercentage.removeListener(priceAsPercentageListener); priceAsPercentage.removeListener(marketPriceMarginListener);
dataModel.usePercentageBasedPrice.removeListener(usePercentageBasedPriceListener); dataModel.useMarketBasedPrice.removeListener(useMarketBasedPriceListener);
volume.removeListener(volumeListener); volume.removeListener(volumeListener);
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding // Binding with Bindings.createObjectBinding does not work because of bi-directional binding
@ -542,9 +542,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
} }
void onFocusOutPriceAsPercentageTextField(boolean oldValue, boolean newValue, String userInput) { void onFocusOutPriceAsPercentageTextField(boolean oldValue, boolean newValue, String userInput) {
priceAsPercentageIsInput = !oldValue && newValue; inputIsMarketBasedPrice = !oldValue && newValue;
if (oldValue && !newValue) if (oldValue && !newValue)
priceAsPercentage.set(formatter.formatToNumberString(dataModel.getPercentageBasedPrice() * 100, 2)); priceAsPercentage.set(formatter.formatToNumberString(dataModel.getMarketPriceMargin() * 100, 2));
} }
void onFocusOutVolumeTextField(boolean oldValue, boolean newValue, String userInput) { void onFocusOutVolumeTextField(boolean oldValue, boolean newValue, String userInput) {

View file

@ -263,7 +263,7 @@ class OfferBookViewModel extends ActivatableViewModel {
Offer offer = item.getOffer(); Offer offer = item.getOffer();
Fiat price = offer.getPrice(); Fiat price = offer.getPrice();
String postFix = ""; String postFix = "";
if (offer.getUsePercentageBasedPrice()) { if (offer.getUseMarketBasedPrice()) {
postFix = " (" + formatter.formatToPercentWithSymbol(offer.getMarketPriceMargin()) + ")"; postFix = " (" + formatter.formatToPercentWithSymbol(offer.getMarketPriceMargin()) + ")";
} }
if (showAllTradeCurrenciesProperty.get()) if (showAllTradeCurrenciesProperty.get())

View file

@ -196,7 +196,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
public void initWithData(Offer offer) { public void initWithData(Offer offer) {
model.initWithData(offer); model.initWithData(offer);
priceAsPercentageInputBox.setVisible(offer.getUsePercentageBasedPrice()); priceAsPercentageInputBox.setVisible(offer.getUseMarketBasedPrice());
if (model.getOffer().getDirection() == Offer.Direction.SELL) { if (model.getOffer().getDirection() == Offer.Direction.SELL) {
imageView.setId("image-buy-large"); imageView.setId("image-buy-large");