mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Add trigger price to OpenOffersView
This commit is contained in:
parent
f096351d60
commit
39893a6aaf
11 changed files with 101 additions and 32 deletions
|
@ -34,6 +34,7 @@ import bisq.core.notifications.alerts.TradeEvents;
|
|||
import bisq.core.notifications.alerts.market.MarketAlerts;
|
||||
import bisq.core.notifications.alerts.price.PriceAlert;
|
||||
import bisq.core.offer.OpenOfferManager;
|
||||
import bisq.core.offer.PriceEventHandler;
|
||||
import bisq.core.payment.RevolutAccount;
|
||||
import bisq.core.payment.TradeLimits;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
|
@ -106,6 +107,7 @@ public class DomainInitialisation {
|
|||
private final MarketAlerts marketAlerts;
|
||||
private final User user;
|
||||
private final DaoStateSnapshotService daoStateSnapshotService;
|
||||
private final PriceEventHandler priceEventHandler;
|
||||
|
||||
@Inject
|
||||
public DomainInitialisation(ClockWatcher clockWatcher,
|
||||
|
@ -141,7 +143,8 @@ public class DomainInitialisation {
|
|||
PriceAlert priceAlert,
|
||||
MarketAlerts marketAlerts,
|
||||
User user,
|
||||
DaoStateSnapshotService daoStateSnapshotService) {
|
||||
DaoStateSnapshotService daoStateSnapshotService,
|
||||
PriceEventHandler priceEventHandler) {
|
||||
this.clockWatcher = clockWatcher;
|
||||
this.tradeLimits = tradeLimits;
|
||||
this.arbitrationManager = arbitrationManager;
|
||||
|
@ -176,6 +179,7 @@ public class DomainInitialisation {
|
|||
this.marketAlerts = marketAlerts;
|
||||
this.user = user;
|
||||
this.daoStateSnapshotService = daoStateSnapshotService;
|
||||
this.priceEventHandler = priceEventHandler;
|
||||
}
|
||||
|
||||
public void initDomainServices(Consumer<String> rejectedTxErrorMessageHandler,
|
||||
|
@ -254,6 +258,7 @@ public class DomainInitialisation {
|
|||
disputeMsgEvents.onAllServicesInitialized();
|
||||
priceAlert.onAllServicesInitialized();
|
||||
marketAlerts.onAllServicesInitialized();
|
||||
priceEventHandler.onAllServicesInitialized();
|
||||
|
||||
if (revolutAccountsUpdateHandler != null) {
|
||||
revolutAccountsUpdateHandler.accept(user.getPaymentAccountsAsObservable().stream()
|
||||
|
|
|
@ -92,7 +92,8 @@ public class PriceEventHandler {
|
|||
}
|
||||
|
||||
String currencyCode = openOffer.getOffer().getCurrencyCode();
|
||||
int smallestUnitExponent = CurrencyUtil.isCryptoCurrency(currencyCode) ?
|
||||
boolean cryptoCurrency = CurrencyUtil.isCryptoCurrency(currencyCode);
|
||||
int smallestUnitExponent = cryptoCurrency ?
|
||||
Altcoin.SMALLEST_UNIT_EXPONENT :
|
||||
Fiat.SMALLEST_UNIT_EXPONENT;
|
||||
long marketPriceAsLong = roundDoubleToLong(
|
||||
|
@ -100,13 +101,15 @@ public class PriceEventHandler {
|
|||
long triggerPrice = openOffer.getTriggerPrice();
|
||||
if (triggerPrice > 0) {
|
||||
OfferPayload.Direction direction = openOffer.getOffer().getDirection();
|
||||
boolean triggered = direction == OfferPayload.Direction.BUY ?
|
||||
marketPriceAsLong > triggerPrice :
|
||||
marketPriceAsLong < triggerPrice;
|
||||
boolean isSellOffer = direction == OfferPayload.Direction.SELL;
|
||||
boolean condition = isSellOffer && !cryptoCurrency || !isSellOffer && cryptoCurrency;
|
||||
boolean triggered = condition ?
|
||||
marketPriceAsLong < triggerPrice :
|
||||
marketPriceAsLong > triggerPrice;
|
||||
if (triggered) {
|
||||
log.error("Market price exceeded the trigger price of the open offer. " +
|
||||
"We deactivate the open offer with ID {}. Currency: {}; offer direction: {}; " +
|
||||
"Market price: {}; Upper price threshold : {}",
|
||||
log.info("Market price exceeded the trigger price of the open offer.\n" +
|
||||
"We deactivate the open offer with ID {}.\nCurrency: {};\nOffer direction: {};\n" +
|
||||
"Market price: {};\nTrigger price : {}",
|
||||
openOffer.getOffer().getShortId(),
|
||||
currencyCode,
|
||||
direction,
|
||||
|
|
|
@ -221,6 +221,7 @@ shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transac
|
|||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.enabled=Enabled
|
||||
shared.triggerPrice=Trigger price
|
||||
|
||||
|
||||
####################################################################
|
||||
|
|
|
@ -679,7 +679,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
|||
return tradeCurrencyCode;
|
||||
}
|
||||
|
||||
String getCurrencyCode() {
|
||||
public String getCurrencyCode() {
|
||||
return tradeCurrencyCode.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -106,8 +106,8 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
protected final CoinFormatter btcFormatter;
|
||||
private final BsqFormatter bsqFormatter;
|
||||
private final FiatVolumeValidator fiatVolumeValidator;
|
||||
private final FiatPriceValidator fiatPriceValidator, fiatTriggerPriceValidator;
|
||||
private final AltcoinValidator altcoinValidator, altcoinTriggerPriceValidator;
|
||||
private final FiatPriceValidator fiatPriceValidator;
|
||||
private final AltcoinValidator altcoinValidator;
|
||||
protected final OfferUtil offerUtil;
|
||||
|
||||
private String amountDescription;
|
||||
|
@ -223,9 +223,6 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
this.bsqFormatter = bsqFormatter;
|
||||
this.offerUtil = offerUtil;
|
||||
|
||||
fiatTriggerPriceValidator = new FiatPriceValidator();
|
||||
altcoinTriggerPriceValidator = new AltcoinValidator();
|
||||
|
||||
paymentLabel = Res.get("createOffer.fundsBox.paymentLabel", dataModel.shortOfferId);
|
||||
|
||||
if (dataModel.getAddressEntry() != null) {
|
||||
|
@ -788,8 +785,13 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
}
|
||||
}
|
||||
|
||||
void onTriggerPriceTextFieldChanged() {
|
||||
public void onTriggerPriceTextFieldChanged() {
|
||||
String triggerPriceAsString = triggerPrice.get();
|
||||
|
||||
// Error field does not update if there was an error and then another different error
|
||||
// if not reset here. Not clear why...
|
||||
triggerPriceValidationResult.set(new InputValidator.ValidationResult(true));
|
||||
|
||||
InputValidator.ValidationResult result = PriceUtil.isTriggerPriceValid(triggerPriceAsString,
|
||||
dataModel.getPrice().get(),
|
||||
dataModel.isSellOffer(),
|
||||
|
|
|
@ -313,7 +313,6 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
}
|
||||
|
||||
private void onWidthChange(double width) {
|
||||
log.error("onWidthChange " + width);
|
||||
txFeeColumn.setVisible(width > 1200);
|
||||
tradeFeeColumn.setVisible(width > 1300);
|
||||
buyerSecurityDepositColumn.setVisible(width > 1400);
|
||||
|
|
|
@ -170,7 +170,10 @@ class EditOfferDataModel extends MutableOfferDataModel {
|
|||
setPrice(offer.getPrice());
|
||||
setVolume(offer.getVolume());
|
||||
setUseMarketBasedPrice(offer.isUseMarketBasedPrice());
|
||||
if (offer.isUseMarketBasedPrice()) setMarketPriceMargin(offer.getMarketPriceMargin());
|
||||
setTriggerPrice(openOffer.getTriggerPrice());
|
||||
if (offer.isUseMarketBasedPrice()) {
|
||||
setMarketPriceMargin(offer.getMarketPriceMargin());
|
||||
}
|
||||
}
|
||||
|
||||
public void onStartEditOffer(ErrorMessageHandler errorMessageHandler) {
|
||||
|
|
|
@ -80,15 +80,22 @@ class EditOfferViewModel extends MutableOfferViewModel<EditOfferDataModel> {
|
|||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
dataModel.populateData();
|
||||
|
||||
long triggerPriceAsLong = dataModel.getTriggerPrice();
|
||||
dataModel.setTriggerPrice(triggerPriceAsLong);
|
||||
if (triggerPriceAsLong > 0) {
|
||||
triggerPrice.set(PriceUtil.formatMarketPrice(triggerPriceAsLong, dataModel.getCurrencyCode()));
|
||||
} else {
|
||||
triggerPrice.set("");
|
||||
}
|
||||
onTriggerPriceTextFieldChanged();
|
||||
}
|
||||
|
||||
public void applyOpenOffer(OpenOffer openOffer) {
|
||||
dataModel.reset();
|
||||
dataModel.applyOpenOffer(openOffer);
|
||||
|
||||
dataModel.setTriggerPrice(openOffer.getTriggerPrice());
|
||||
triggerPrice.set(PriceUtil.formatMarketPrice(openOffer.getTriggerPrice(), openOffer.getOffer().getCurrencyCode()));
|
||||
}
|
||||
|
||||
public void onStartEditOffer(ErrorMessageHandler errorMessageHandler) {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<TableColumn fx:id="marketColumn" minWidth="75"/>
|
||||
<TableColumn fx:id="priceColumn" minWidth="100"/>
|
||||
<TableColumn fx:id="deviationColumn" minWidth="70"/>
|
||||
<TableColumn fx:id="triggerPriceColumn" minWidth="70"/>
|
||||
<TableColumn fx:id="amountColumn" minWidth="110"/>
|
||||
<TableColumn fx:id="volumeColumn" minWidth="110"/>
|
||||
<TableColumn fx:id="paymentMethodColumn" minWidth="120" maxWidth="170"/>
|
||||
|
|
|
@ -89,7 +89,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
@FXML
|
||||
TableColumn<OpenOfferListItem, OpenOfferListItem> priceColumn, deviationColumn, amountColumn, volumeColumn,
|
||||
marketColumn, directionColumn, dateColumn, offerIdColumn, deactivateItemColumn,
|
||||
removeItemColumn, editItemColumn, paymentMethodColumn;
|
||||
removeItemColumn, editItemColumn, triggerPriceColumn, paymentMethodColumn;
|
||||
@FXML
|
||||
HBox searchBox;
|
||||
@FXML
|
||||
|
@ -113,6 +113,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
private FilteredList<OpenOfferListItem> filteredList;
|
||||
private ChangeListener<String> filterTextFieldListener;
|
||||
private PortfolioView.OpenOfferActionHandler openOfferActionHandler;
|
||||
private ChangeListener<Number> widthListener;
|
||||
|
||||
@Inject
|
||||
public OpenOffersView(OpenOffersViewModel model, Navigation navigation, OfferDetailsWindow offerDetailsWindow) {
|
||||
|
@ -123,6 +124,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
widthListener = (observable, oldValue, newValue) -> onWidthChange((double) newValue);
|
||||
paymentMethodColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.paymentMethod")));
|
||||
priceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.price")));
|
||||
deviationColumn.setGraphic(new AutoTooltipTableColumn<>(Res.get("shared.deviation"),
|
||||
|
@ -133,6 +135,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
directionColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.offerType")));
|
||||
dateColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.dateTime")));
|
||||
offerIdColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.offerId")));
|
||||
triggerPriceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.triggerPrice")));
|
||||
deactivateItemColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.enabled")));
|
||||
editItemColumn.setGraphic(new AutoTooltipLabel(""));
|
||||
removeItemColumn.setGraphic(new AutoTooltipLabel(""));
|
||||
|
@ -148,6 +151,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
setDateColumnCellFactory();
|
||||
setDeactivateColumnCellFactory();
|
||||
setEditColumnCellFactory();
|
||||
setTriggerPriceColumnCellFactory();
|
||||
setRemoveColumnCellFactory();
|
||||
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
@ -159,6 +163,8 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
amountColumn.setComparator(Comparator.comparing(o -> o.getOffer().getAmount()));
|
||||
priceColumn.setComparator(Comparator.comparing(o -> o.getOffer().getPrice(), Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
deviationColumn.setComparator(Comparator.comparing(model::getPriceDeviationAsDouble, Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
triggerPriceColumn.setComparator(Comparator.comparing(o -> o.getOpenOffer().getTriggerPrice(),
|
||||
Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
volumeColumn.setComparator(Comparator.comparing(o -> o.getOffer().getVolume(), Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
dateColumn.setComparator(Comparator.comparing(o -> o.getOffer().getDate()));
|
||||
paymentMethodColumn.setComparator(Comparator.comparing(o -> Res.get(o.getOffer().getPaymentMethod().getId())));
|
||||
|
@ -245,6 +251,18 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
|
||||
filterTextField.textProperty().addListener(filterTextFieldListener);
|
||||
applyFilteredListPredicate(filterTextField.getText());
|
||||
|
||||
root.widthProperty().addListener(widthListener);
|
||||
onWidthChange(root.getWidth());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
sortedList.comparatorProperty().unbind();
|
||||
exportButton.setOnAction(null);
|
||||
|
||||
filterTextField.textProperty().removeListener(filterTextFieldListener);
|
||||
root.widthProperty().removeListener(widthListener);
|
||||
}
|
||||
|
||||
private void updateSelectToggleButtonState() {
|
||||
|
@ -264,14 +282,6 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
sortedList.comparatorProperty().unbind();
|
||||
exportButton.setOnAction(null);
|
||||
|
||||
filterTextField.textProperty().removeListener(filterTextFieldListener);
|
||||
}
|
||||
|
||||
private void applyFilteredListPredicate(String filterString) {
|
||||
filteredList.setPredicate(item -> {
|
||||
if (filterString.isEmpty())
|
||||
|
@ -312,6 +322,10 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
});
|
||||
}
|
||||
|
||||
private void onWidthChange(double width) {
|
||||
triggerPriceColumn.setVisible(width > 1200);
|
||||
}
|
||||
|
||||
private void onDeactivateOpenOffer(OpenOffer openOffer) {
|
||||
if (model.isBootstrappedOrShowPopup()) {
|
||||
model.onDeactivateOpenOffer(openOffer,
|
||||
|
@ -514,6 +528,30 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
});
|
||||
}
|
||||
|
||||
private void setTriggerPriceColumnCellFactory() {
|
||||
triggerPriceColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
|
||||
triggerPriceColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
@Override
|
||||
public TableCell<OpenOfferListItem, OpenOfferListItem> call(
|
||||
TableColumn<OpenOfferListItem, OpenOfferListItem> column) {
|
||||
return new TableCell<>() {
|
||||
@Override
|
||||
public void updateItem(final OpenOfferListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
getStyleClass().removeAll("offer-disabled");
|
||||
if (item != null) {
|
||||
if (model.isDeactivated(item)) getStyleClass().add("offer-disabled");
|
||||
setGraphic(new AutoTooltipLabel(model.getTriggerPrice(item)));
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setVolumeColumnCellFactory() {
|
||||
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
volumeColumn.setCellFactory(
|
||||
|
@ -660,7 +698,6 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
};
|
||||
}
|
||||
});
|
||||
deactivateItemColumn.setSortable(false);
|
||||
}
|
||||
|
||||
private void setRemoveColumnCellFactory() {
|
||||
|
@ -695,7 +732,6 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
};
|
||||
}
|
||||
});
|
||||
removeItemColumn.setSortable(false);
|
||||
}
|
||||
|
||||
private void setEditColumnCellFactory() {
|
||||
|
@ -729,7 +765,6 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
};
|
||||
}
|
||||
});
|
||||
editItemColumn.setSortable(false);
|
||||
}
|
||||
|
||||
public void setOpenOfferActionHandler(PortfolioView.OpenOfferActionHandler openOfferActionHandler) {
|
||||
|
|
|
@ -171,4 +171,17 @@ class OpenOffersViewModel extends ActivatableWithDataModel<OpenOffersDataModel>
|
|||
btcFormatter.formatCoinWithCode(offer.getMakerFee()) :
|
||||
bsqFormatter.formatCoinWithCode(offer.getMakerFee());
|
||||
}
|
||||
|
||||
String getTriggerPrice(OpenOfferListItem item) {
|
||||
if ((item == null))
|
||||
return "";
|
||||
Offer offer = item.getOffer();
|
||||
if (offer.isUseMarketBasedPrice()) {
|
||||
return PriceUtil.formatMarketPrice(item.getOpenOffer().getTriggerPrice(), offer.getCurrencyCode());
|
||||
} else {
|
||||
return Res.get("shared.na");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue