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()));
}
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());
}
}
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);
}
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);
}
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);
}
Aggregations