Search in sources :

Example 1 with TradeStatistics2

use of bisq.core.trade.statistics.TradeStatistics2 in project bisq-desktop by bisq-network.

the class TradesChartsViewModel method updateChartData.

private void updateChartData() {
    tradeStatisticsByCurrency.setAll(tradeStatisticsManager.getObservableTradeStatisticsSet().stream().filter(e -> showAllTradeCurrenciesProperty.get() || e.getCurrencyCode().equals(getCurrencyCode())).collect(Collectors.toList()));
    // Generate date range and create sets for all ticks
    itemsPerInterval = new HashMap<>();
    Date time = new Date();
    for (long i = maxTicks + 1; i >= 0; --i) {
        Set<TradeStatistics2> set = new HashSet<>();
        Pair<Date, Set<TradeStatistics2>> pair = new Pair<>((Date) time.clone(), set);
        itemsPerInterval.put(i, pair);
        time.setTime(time.getTime() - 1);
        time = roundToTick(time, tickUnit);
    }
    // Get all entries for the defined time interval
    tradeStatisticsByCurrency.stream().forEach(e -> {
        for (long i = maxTicks; i > 0; --i) {
            Pair<Date, Set<TradeStatistics2>> p = itemsPerInterval.get(i);
            if (e.getTradeDate().after(p.getKey())) {
                p.getValue().add(e);
                break;
            }
        }
    });
    // create CandleData for defined time interval
    List<CandleData> candleDataList = itemsPerInterval.entrySet().stream().filter(entry -> entry.getKey() >= 0 && !entry.getValue().getValue().isEmpty()).map(entry -> getCandleData(entry.getKey(), entry.getValue().getValue())).collect(Collectors.toList());
    candleDataList.sort((o1, o2) -> (o1.tick < o2.tick ? -1 : (o1.tick == o2.tick ? 0 : 1)));
    // noinspection Convert2Diamond
    priceItems.setAll(candleDataList.stream().map(e -> new XYChart.Data<Number, Number>(e.tick, e.open, e)).collect(Collectors.toList()));
    // noinspection Convert2Diamond
    volumeItems.setAll(candleDataList.stream().map(e -> new XYChart.Data<Number, Number>(e.tick, e.accumulatedAmount, e)).collect(Collectors.toList()));
}
Also used : Altcoin(bisq.core.monetary.Altcoin) GUIUtil(bisq.desktop.util.GUIUtil) TradeCurrency(bisq.core.locale.TradeCurrency) CurrencyListItem(bisq.desktop.util.CurrencyListItem) Coin(org.bitcoinj.core.Coin) Date(java.util.Date) CurrencyList(bisq.desktop.util.CurrencyList) Inject(com.google.inject.Inject) ZonedDateTime(java.time.ZonedDateTime) SetChangeListener(javafx.collections.SetChangeListener) LocalDateTime(java.time.LocalDateTime) FXCollections(javafx.collections.FXCollections) HashMap(java.util.HashMap) XYChart(javafx.scene.chart.XYChart) TradeStatisticsManager(bisq.core.trade.statistics.TradeStatisticsManager) BSFormatter(bisq.desktop.util.BSFormatter) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Map(java.util.Map) CurrencyUtil(bisq.core.locale.CurrencyUtil) Navigation(bisq.desktop.Navigation) ObjectProperty(javafx.beans.property.ObjectProperty) Pair(javafx.util.Pair) GlobalSettings(bisq.core.locale.GlobalSettings) Set(java.util.Set) TradeStatistics2(bisq.core.trade.statistics.TradeStatistics2) MathUtils(bisq.common.util.MathUtils) Collectors(java.util.stream.Collectors) ZoneId(java.time.ZoneId) ActivatableViewModel(bisq.desktop.common.model.ActivatableViewModel) MainView(bisq.desktop.main.MainView) BooleanProperty(javafx.beans.property.BooleanProperty) List(java.util.List) PriceFeedService(bisq.core.provider.price.PriceFeedService) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) ChronoUnit(java.time.temporal.ChronoUnit) CryptoCurrency(bisq.core.locale.CryptoCurrency) PreferencesView(bisq.desktop.main.settings.preferences.PreferencesView) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) CandleData(bisq.desktop.main.market.trades.charts.CandleData) Preferences(bisq.core.user.Preferences) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ObservableList(javafx.collections.ObservableList) SettingsView(bisq.desktop.main.settings.SettingsView) HashSet(java.util.HashSet) Set(java.util.Set) CandleData(bisq.desktop.main.market.trades.charts.CandleData) TradeStatistics2(bisq.core.trade.statistics.TradeStatistics2) Date(java.util.Date) XYChart(javafx.scene.chart.XYChart) HashSet(java.util.HashSet) Pair(javafx.util.Pair)

Example 2 with TradeStatistics2

use of bisq.core.trade.statistics.TradeStatistics2 in project bisq-desktop by bisq-network.

the class TradesChartsViewModelTest method testItemLists.

@Test
public void testItemLists() throws ParseException {
    // Helper class to add historic trades
    class Trade {

        Trade(String date, String size, String price, String cc) {
            try {
                this.date = dateFormat.parse(date);
            } catch (ParseException p) {
                this.date = new Date();
            }
            this.size = size;
            this.price = price;
            this.cc = cc;
        }

        Date date;

        String size;

        String price;

        String cc;
    }
    ;
    // Trade EUR
    model.selectedTradeCurrencyProperty.setValue(new FiatCurrency("EUR"));
    ArrayList<Trade> trades = new ArrayList<Trade>();
    // Set predetermined time to use as "now" during test
    // Monday
    Date test_time = dateFormat.parse("2018-01-01T00:00:05");
    new MockUp<System>() {

        @Mock
        long currentTimeMillis() {
            return test_time.getTime();
        }
    };
    // Two trades 10 seconds apart, different YEAR, MONTH, WEEK, DAY, HOUR, MINUTE_10
    trades.add(new Trade("2017-12-31T23:59:52", "1", "100", "EUR"));
    trades.add(new Trade("2018-01-01T00:00:02", "1", "110", "EUR"));
    Set<TradeStatistics2> set = new HashSet<>();
    trades.forEach(t -> {
        set.add(new TradeStatistics2(offer, Price.parse(t.cc, t.price), Coin.parseCoin(t.size), t.date, null));
    });
    ObservableSet<TradeStatistics2> tradeStats = FXCollections.observableSet(set);
    // Run test for each tick type
    for (TradesChartsViewModel.TickUnit tick : TradesChartsViewModel.TickUnit.values()) {
        new Expectations() {

            {
                tsm.getObservableTradeStatisticsSet();
                result = tradeStats;
            }
        };
        // Trigger chart update
        model.setTickUnit(tick);
        assertEquals(model.selectedTradeCurrencyProperty.get().getCode(), tradeStats.iterator().next().getCurrencyCode());
        assertEquals(2, model.priceItems.size());
        assertEquals(2, model.volumeItems.size());
    }
}
Also used : Expectations(mockit.Expectations) ArrayList(java.util.ArrayList) TradeStatistics2(bisq.core.trade.statistics.TradeStatistics2) MockUp(mockit.MockUp) Date(java.util.Date) FiatCurrency(bisq.core.locale.FiatCurrency) ParseException(java.text.ParseException) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 3 with TradeStatistics2

use of bisq.core.trade.statistics.TradeStatistics2 in project bisq-desktop by bisq-network.

the class TradesChartsView method createTable.

// /////////////////////////////////////////////////////////////////////////////////////////
// Table
// /////////////////////////////////////////////////////////////////////////////////////////
private void createTable() {
    tableView = new TableView<>();
    tableView.setMinHeight(140);
    tableView.setPrefHeight(140);
    VBox.setVgrow(tableView, Priority.ALWAYS);
    // date
    TableColumn<TradeStatistics2, TradeStatistics2> dateColumn = new AutoTooltipTableColumn<TradeStatistics2, TradeStatistics2>(Res.get("shared.dateTime")) {

        {
            setMinWidth(240);
            setMaxWidth(240);
        }
    };
    dateColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    dateColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setText(formatter.formatDateTime(item.getTradeDate()));
                    else
                        setText("");
                }
            };
        }
    });
    dateColumn.setComparator((o1, o2) -> o1.getTradeDate().compareTo(o2.getTradeDate()));
    tableView.getColumns().add(dateColumn);
    // market
    marketColumn = new AutoTooltipTableColumn<TradeStatistics2, TradeStatistics2>(Res.get("shared.market")) {

        {
            setMinWidth(130);
            setMaxWidth(130);
        }
    };
    marketColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    marketColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setText(formatter.getCurrencyPair(item.getCurrencyCode()));
                    else
                        setText("");
                }
            };
        }
    });
    marketColumn.setComparator((o1, o2) -> o1.getTradeDate().compareTo(o2.getTradeDate()));
    tableView.getColumns().add(marketColumn);
    // price
    priceColumn = new TableColumn<>();
    priceColumn.getStyleClass().add("number-column");
    priceColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    priceColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setText(formatter.formatPrice(item.getTradePrice()));
                    else
                        setText("");
                }
            };
        }
    });
    priceColumn.setComparator((o1, o2) -> o1.getTradePrice().compareTo(o2.getTradePrice()));
    tableView.getColumns().add(priceColumn);
    // amount
    TableColumn<TradeStatistics2, TradeStatistics2> amountColumn = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", Res.getBaseCurrencyCode()));
    amountColumn.getStyleClass().add("number-column");
    amountColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    amountColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setGraphic(new ColoredDecimalPlacesWithZerosText(formatter.formatCoin(item.getTradeAmount(), 4), GUIUtil.AMOUNT_DECIMALS_WITH_ZEROS));
                    else
                        setText("");
                }
            };
        }
    });
    amountColumn.setComparator((o1, o2) -> o1.getTradeAmount().compareTo(o2.getTradeAmount()));
    tableView.getColumns().add(amountColumn);
    // volume
    volumeColumn = new TableColumn<>();
    volumeColumn.getStyleClass().add("number-column");
    volumeColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    volumeColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setText(model.showAllTradeCurrenciesProperty.get() ? formatter.formatVolumeWithCode(item.getTradeVolume()) : formatter.formatVolume(item.getTradeVolume()));
                    else
                        setText("");
                }
            };
        }
    });
    volumeColumn.setComparator((o1, o2) -> {
        final Volume tradeVolume1 = o1.getTradeVolume();
        final Volume tradeVolume2 = o2.getTradeVolume();
        return tradeVolume1 != null && tradeVolume2 != null ? tradeVolume1.compareTo(tradeVolume2) : 0;
    });
    tableView.getColumns().add(volumeColumn);
    // paymentMethod
    TableColumn<TradeStatistics2, TradeStatistics2> paymentMethodColumn = new AutoTooltipTableColumn<>(Res.get("shared.paymentMethod"));
    paymentMethodColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    paymentMethodColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setText(getPaymentMethodLabel(item));
                    else
                        setText("");
                }
            };
        }
    });
    paymentMethodColumn.setComparator((o1, o2) -> getPaymentMethodLabel(o1).compareTo(getPaymentMethodLabel(o2)));
    tableView.getColumns().add(paymentMethodColumn);
    // direction
    TableColumn<TradeStatistics2, TradeStatistics2> directionColumn = new AutoTooltipTableColumn<>(Res.get("shared.offerType"));
    directionColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
    directionColumn.setCellFactory(new Callback<TableColumn<TradeStatistics2, TradeStatistics2>, TableCell<TradeStatistics2, TradeStatistics2>>() {

        @Override
        public TableCell<TradeStatistics2, TradeStatistics2> call(TableColumn<TradeStatistics2, TradeStatistics2> column) {
            return new TableCell<TradeStatistics2, TradeStatistics2>() {

                @Override
                public void updateItem(final TradeStatistics2 item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item != null)
                        setText(getDirectionLabel(item));
                    else
                        setText("");
                }
            };
        }
    });
    directionColumn.setComparator((o1, o2) -> getDirectionLabel(o1).compareTo(getDirectionLabel(o2)));
    tableView.getColumns().add(directionColumn);
    tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    Label placeholder = new AutoTooltipLabel(Res.get("table.placeholder.noData"));
    placeholder.setWrapText(true);
    tableView.setPlaceholder(placeholder);
    dateColumn.setSortType(TableColumn.SortType.DESCENDING);
    tableView.getSortOrder().add(dateColumn);
}
Also used : TradeStatistics2(bisq.core.trade.statistics.TradeStatistics2) AutoTooltipLabel(bisq.desktop.components.AutoTooltipLabel) Label(javafx.scene.control.Label) AutoTooltipTableColumn(bisq.desktop.components.AutoTooltipTableColumn) TableColumn(javafx.scene.control.TableColumn) TableCell(javafx.scene.control.TableCell) Volume(bisq.core.monetary.Volume) AutoTooltipTableColumn(bisq.desktop.components.AutoTooltipTableColumn) ColoredDecimalPlacesWithZerosText(bisq.desktop.components.ColoredDecimalPlacesWithZerosText) AutoTooltipLabel(bisq.desktop.components.AutoTooltipLabel)

Example 4 with TradeStatistics2

use of bisq.core.trade.statistics.TradeStatistics2 in project bisq-desktop by bisq-network.

the class TradesChartsViewModel method getCandleData.

@VisibleForTesting
CandleData getCandleData(long tick, Set<TradeStatistics2> set) {
    long open = 0;
    long close = 0;
    long high = 0;
    long low = 0;
    long accumulatedVolume = 0;
    long accumulatedAmount = 0;
    long numTrades = set.size();
    for (TradeStatistics2 item : set) {
        long tradePriceAsLong = item.getTradePrice().getValue();
        if (CurrencyUtil.isCryptoCurrency(getCurrencyCode())) {
            low = (low != 0) ? Math.max(low, tradePriceAsLong) : tradePriceAsLong;
            high = (high != 0) ? Math.min(high, tradePriceAsLong) : tradePriceAsLong;
        } else {
            low = (low != 0) ? Math.min(low, tradePriceAsLong) : tradePriceAsLong;
            high = (high != 0) ? Math.max(high, tradePriceAsLong) : tradePriceAsLong;
        }
        accumulatedVolume += (item.getTradeVolume() != null) ? item.getTradeVolume().getValue() : 0;
        accumulatedAmount += item.getTradeAmount().getValue();
    }
    List<TradeStatistics2> list = new ArrayList<>(set);
    list.sort((o1, o2) -> (o1.getTradeDate().getTime() < o2.getTradeDate().getTime() ? -1 : (o1.getTradeDate().getTime() == o2.getTradeDate().getTime() ? 0 : 1)));
    if (list.size() > 0) {
        open = list.get(0).getTradePrice().getValue();
        close = list.get(list.size() - 1).getTradePrice().getValue();
    }
    long averagePrice;
    boolean isBullish;
    if (CurrencyUtil.isCryptoCurrency(getCurrencyCode())) {
        isBullish = close < open;
        double accumulatedAmountAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedAmount, Altcoin.SMALLEST_UNIT_EXPONENT);
        averagePrice = MathUtils.roundDoubleToLong(accumulatedAmountAsDouble / (double) accumulatedVolume);
    } else {
        isBullish = close > open;
        double accumulatedVolumeAsDouble = MathUtils.scaleUpByPowerOf10((double) accumulatedVolume, Coin.SMALLEST_UNIT_EXPONENT);
        averagePrice = MathUtils.roundDoubleToLong(accumulatedVolumeAsDouble / (double) accumulatedAmount);
    }
    final Date dateFrom = new Date(getTimeFromTickIndex(tick));
    final Date dateTo = new Date(getTimeFromTickIndex(tick + 1));
    String dateString = tickUnit.ordinal() > TickUnit.DAY.ordinal() ? formatter.formatDateTimeSpan(dateFrom, dateTo) : formatter.formatDate(dateFrom) + " - " + formatter.formatDate(dateTo);
    return new CandleData(tick, open, close, high, low, averagePrice, accumulatedAmount, accumulatedVolume, numTrades, isBullish, dateString);
}
Also used : CandleData(bisq.desktop.main.market.trades.charts.CandleData) TradeStatistics2(bisq.core.trade.statistics.TradeStatistics2) ArrayList(java.util.ArrayList) Date(java.util.Date) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 5 with TradeStatistics2

use of bisq.core.trade.statistics.TradeStatistics2 in project bisq-desktop by bisq-network.

the class TradesChartsViewModelTest method testGetCandleData.

@SuppressWarnings("ConstantConditions")
@Test
public void testGetCandleData() {
    model.selectedTradeCurrencyProperty.setValue(new FiatCurrency("EUR"));
    long low = Fiat.parseFiat("EUR", "500").value;
    long open = Fiat.parseFiat("EUR", "520").value;
    long close = Fiat.parseFiat("EUR", "580").value;
    long high = Fiat.parseFiat("EUR", "600").value;
    long average = Fiat.parseFiat("EUR", "550").value;
    long amount = Coin.parseCoin("4").value;
    long volume = Fiat.parseFiat("EUR", "2200").value;
    boolean isBullish = true;
    Set<TradeStatistics2> set = new HashSet<>();
    final Date now = new Date();
    set.add(new TradeStatistics2(offer, Price.parse("EUR", "520"), Coin.parseCoin("1"), new Date(now.getTime()), null));
    set.add(new TradeStatistics2(offer, Price.parse("EUR", "500"), Coin.parseCoin("1"), new Date(now.getTime() + 100), null));
    set.add(new TradeStatistics2(offer, Price.parse("EUR", "600"), Coin.parseCoin("1"), new Date(now.getTime() + 200), null));
    set.add(new TradeStatistics2(offer, Price.parse("EUR", "580"), Coin.parseCoin("1"), new Date(now.getTime() + 300), null));
    CandleData candleData = model.getCandleData(model.roundToTick(now, TradesChartsViewModel.TickUnit.DAY).getTime(), set);
    assertEquals(open, candleData.open);
    assertEquals(close, candleData.close);
    assertEquals(high, candleData.high);
    assertEquals(low, candleData.low);
    assertEquals(average, candleData.average);
    assertEquals(amount, candleData.accumulatedAmount);
    assertEquals(volume, candleData.accumulatedVolume);
    assertEquals(isBullish, candleData.isBullish);
}
Also used : CandleData(bisq.desktop.main.market.trades.charts.CandleData) TradeStatistics2(bisq.core.trade.statistics.TradeStatistics2) FiatCurrency(bisq.core.locale.FiatCurrency) Date(java.util.Date) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

TradeStatistics2 (bisq.core.trade.statistics.TradeStatistics2)7 Date (java.util.Date)5 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 CandleData (bisq.desktop.main.market.trades.charts.CandleData)3 MathUtils (bisq.common.util.MathUtils)2 CurrencyUtil (bisq.core.locale.CurrencyUtil)2 FiatCurrency (bisq.core.locale.FiatCurrency)2 TradeCurrency (bisq.core.locale.TradeCurrency)2 Preferences (bisq.core.user.Preferences)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Inject (com.google.inject.Inject)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 Timer (bisq.common.Timer)1 UserThread (bisq.common.UserThread)1 Log (bisq.common.app.Log)1 FaultHandler (bisq.common.handlers.FaultHandler)1 Tuple2 (bisq.common.util.Tuple2)1