From 32e1a5a3accbb8ca98a0632f360ee95f1f844360 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 22 Mar 2016 19:59:37 +0100 Subject: [PATCH] Add check for deviation from market price at create offer --- .../src/main/java/io/bitsquare/app/Log.java | 2 +- .../io/bitsquare/btc/pricefeed/PriceFeed.java | 7 +++ .../java/io/bitsquare/user/Preferences.java | 14 ++++++ .../offer/createoffer/CreateOfferView.java | 5 ++- .../createoffer/CreateOfferViewModel.java | 44 ++++++++++++++++++- .../settings/preferences/PreferencesView.java | 36 ++++++++++++++- 6 files changed, 103 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/io/bitsquare/app/Log.java b/common/src/main/java/io/bitsquare/app/Log.java index fa3b12abba..4a4e04a9c5 100644 --- a/common/src/main/java/io/bitsquare/app/Log.java +++ b/common/src/main/java/io/bitsquare/app/Log.java @@ -60,7 +60,7 @@ public class Log { appender.start(); logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); - logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.INFO); + logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.WARN); logbackLogger.addAppender(appender); // log errors in separate file diff --git a/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java b/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java index 5e1033d77d..89a4c5367d 100644 --- a/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java +++ b/core/src/main/java/io/bitsquare/btc/pricefeed/PriceFeed.java @@ -87,6 +87,13 @@ public class PriceFeed { requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice); } + @Nullable + public MarketPrice getMarketPrice(String currencyCode) { + if (cache.containsKey(currencyCode)) + return cache.get(currencyCode); + else + return null; + } /////////////////////////////////////////////////////////////////////////////////////////// // Setter diff --git a/core/src/main/java/io/bitsquare/user/Preferences.java b/core/src/main/java/io/bitsquare/user/Preferences.java index 4d93a6f5a2..7f3d2dbf39 100644 --- a/core/src/main/java/io/bitsquare/user/Preferences.java +++ b/core/src/main/java/io/bitsquare/user/Preferences.java @@ -106,6 +106,7 @@ public final class Preferences implements Persistable { private Locale preferredLocale; private TradeCurrency preferredTradeCurrency; private long txFeePerKB = FeePolicy.getFeePerKb().value; + private double maxPriceDistanceInPercent; // Observable wrappers transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination); @@ -155,6 +156,10 @@ public final class Preferences implements Persistable { defaultTradeCurrency = preferredTradeCurrency; useTorForBitcoinJ = persisted.getUseTorForBitcoinJ(); showOwnOffersInOfferBook = persisted.getShowOwnOffersInOfferBook(); + maxPriceDistanceInPercent = persisted.getMaxPriceDistanceInPercent(); + // Backward compatible to version 0.3.6. Can be removed after a while + if (maxPriceDistanceInPercent == 0d) + maxPriceDistanceInPercent = 0.2; try { setTxFeePerKB(persisted.getTxFeePerKB()); @@ -174,6 +179,7 @@ public final class Preferences implements Persistable { dontShowAgainMap = new HashMap<>(); preferredLocale = getDefaultLocale(); preferredTradeCurrency = getDefaultTradeCurrency(); + maxPriceDistanceInPercent = 0.2; storage.queueUpForSave(); } @@ -459,4 +465,12 @@ public final class Preferences implements Persistable { public void setShowOwnOffersInOfferBook(boolean showOwnOffersInOfferBook) { this.showOwnOffersInOfferBook = showOwnOffersInOfferBook; } + + public double getMaxPriceDistanceInPercent() { + return maxPriceDistanceInPercent; + } + + public void setMaxPriceDistanceInPercent(double maxPriceDistanceInPercent) { + this.maxPriceDistanceInPercent = maxPriceDistanceInPercent; + } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java index 55f3061cf7..df9950acaf 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferView.java @@ -702,7 +702,10 @@ public class CreateOfferView extends ActivatableViewAndModel onShowPayFundsScreen()); + nextButton.setOnAction(e -> { + if (model.isPriceInRange()) + onShowPayFundsScreen(); + }); } private void addFundingGroup() { diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java index fc6e870d37..66270c3b44 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java @@ -19,10 +19,17 @@ package io.bitsquare.gui.main.offer.createoffer; import io.bitsquare.app.BitsquareApp; import io.bitsquare.btc.FeePolicy; +import io.bitsquare.btc.pricefeed.MarketPrice; +import io.bitsquare.btc.pricefeed.PriceFeed; import io.bitsquare.common.Timer; import io.bitsquare.common.UserThread; +import io.bitsquare.gui.Navigation; import io.bitsquare.gui.common.model.ActivatableWithDataModel; import io.bitsquare.gui.common.model.ViewModel; +import io.bitsquare.gui.main.MainView; +import io.bitsquare.gui.main.overlays.popups.Popup; +import io.bitsquare.gui.main.settings.SettingsView; +import io.bitsquare.gui.main.settings.preferences.PreferencesView; import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.validation.BtcValidator; import io.bitsquare.gui.util.validation.FiatValidator; @@ -32,6 +39,7 @@ import io.bitsquare.locale.TradeCurrency; import io.bitsquare.p2p.P2PService; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.trade.offer.Offer; +import io.bitsquare.user.Preferences; import javafx.beans.property.*; import javafx.beans.value.ChangeListener; import javafx.collections.ObservableList; @@ -41,11 +49,15 @@ import org.bitcoinj.utils.Fiat; import javax.inject.Inject; +import static com.google.common.math.LongMath.checkedPow; import static javafx.beans.binding.Bindings.createStringBinding; class CreateOfferViewModel extends ActivatableWithDataModel implements ViewModel { private final BtcValidator btcValidator; private final P2PService p2PService; + private PriceFeed priceFeed; + private Preferences preferences; + private Navigation navigation; final BSFormatter formatter; private final FiatValidator fiatValidator; @@ -109,13 +121,16 @@ class CreateOfferViewModel extends ActivatableWithDataModel preferences.getMaxPriceDistanceInPercent()) { + Popup popup = new Popup(); + popup.warning("The price you have entered is outside the max. allowed deviation from the market price.\n" + + "The max. allowed deviation is " + + formatter.formatToPercent(preferences.getMaxPriceDistanceInPercent()) + + " and can be adjusted in the preferences.") + .actionButtonText("Change price") + .onAction(() -> popup.hide()) + .closeButtonText("Go to \"Preferences\"") + .onClose(() -> navigation.navigateTo(MainView.class, SettingsView.class, PreferencesView.class)) + .show(); + return false; + } else { + return true; + } + } else { + return true; + } + } + public void onShowPayFundsScreen() { showPayFundsScreenDisplayed = true; updateSpinnerInfo(); diff --git a/gui/src/main/java/io/bitsquare/gui/main/settings/preferences/PreferencesView.java b/gui/src/main/java/io/bitsquare/gui/main/settings/preferences/PreferencesView.java index fed4b0c891..cb267de466 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/settings/preferences/PreferencesView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/settings/preferences/PreferencesView.java @@ -22,8 +22,10 @@ import io.bitsquare.common.util.Tuple2; import io.bitsquare.gui.common.model.Activatable; import io.bitsquare.gui.common.view.ActivatableViewAndModel; import io.bitsquare.gui.common.view.FxmlView; +import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.TitledGroupBg; import io.bitsquare.gui.main.overlays.popups.Popup; +import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.Layout; import io.bitsquare.locale.*; @@ -44,6 +46,7 @@ import javafx.util.Callback; import javafx.util.StringConverter; import javax.inject.Inject; +import java.util.concurrent.TimeUnit; import static io.bitsquare.gui.util.FormBuilder.*; @@ -61,6 +64,7 @@ public class PreferencesView extends ActivatableViewAndModel transactionFeeFocusedListener; private final Preferences preferences; + private BSFormatter formatter; private ListView fiatCurrenciesListView; private ComboBox fiatCurrenciesComboBox; @@ -77,6 +81,9 @@ public class PreferencesView extends ActivatableViewAndModel cryptoCurrencies; public final ObservableList allCryptoCurrencies; public final ObservableList tradeCurrencies; + private InputTextField deviationInputTextField; + private ChangeListener deviationListener; + private ChangeListener deviationFocusedListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -84,9 +91,10 @@ public class PreferencesView extends ActivatableViewAndModel { + try { + String input = newValue.replace("%", ""); + input = input.replace(",", "."); + input = input.replace(" ", ""); + double value = Double.parseDouble(input); + preferences.setMaxPriceDistanceInPercent(value / 100); + } catch (Throwable t) { + log.error("Exception at parseDouble deviation: " + t.toString()); + UserThread.runAfter(() -> deviationInputTextField.setText(formatter.formatToPercent(preferences.getMaxPriceDistanceInPercent())), 100, TimeUnit.MILLISECONDS); + } + }; + deviationFocusedListener = (observable1, oldValue1, newValue1) -> { + if (oldValue1 && !newValue1) + UserThread.runAfter(() -> deviationInputTextField.setText(formatter.formatToPercent(preferences.getMaxPriceDistanceInPercent())), 100, TimeUnit.MILLISECONDS); + }; + // TODO need a bit extra work to separate trade and non trade tx fees before it can be used /*transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second; transactionFeeFocusedListener = (o, oldValue, newValue) -> { @@ -393,6 +419,10 @@ public class PreferencesView extends ActivatableViewAndModel preferences.setBlockChainExplorer(blockChainExplorerComboBox.getSelectionModel().getSelectedItem())); + deviationInputTextField.setText(formatter.formatToPercent(preferences.getMaxPriceDistanceInPercent())); + deviationInputTextField.textProperty().addListener(deviationListener); + deviationInputTextField.focusedProperty().addListener(deviationFocusedListener); + // transactionFeeInputTextField.textProperty().bindBidirectional(transactionFeePerByte); // transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener); } @@ -422,6 +452,8 @@ public class PreferencesView extends ActivatableViewAndModel