mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Integrate initial set of ExchangeRateProviders
Add support for a few exchanges to demonstrate and test the pricenode aggregate rates. The chose exchanges were selected because they each provide a varied list of fiat and altcoins, with a substantial overlap between them. This provides a robust initial set of datapoints and scenarios for aggregate rates.
This commit is contained in:
parent
f650115580
commit
671e80929a
11
build.gradle
11
build.gradle
@ -57,7 +57,7 @@ configure(subprojects) {
|
|||||||
junitVersion = '4.12'
|
junitVersion = '4.12'
|
||||||
jupiterVersion = '5.3.2'
|
jupiterVersion = '5.3.2'
|
||||||
kotlinVersion = '1.3.41'
|
kotlinVersion = '1.3.41'
|
||||||
knowmXchangeVersion = '4.3.3'
|
knowmXchangeVersion = '5.0.0'
|
||||||
langVersion = '3.8'
|
langVersion = '3.8'
|
||||||
logbackVersion = '1.1.11'
|
logbackVersion = '1.1.11'
|
||||||
loggingVersion = '1.2'
|
loggingVersion = '1.2'
|
||||||
@ -458,6 +458,10 @@ configure(project(':pricenode')) {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(":core")
|
compile project(":core")
|
||||||
|
|
||||||
|
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||||
|
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||||
|
|
||||||
implementation "com.google.code.gson:gson:$gsonVersion"
|
implementation "com.google.code.gson:gson:$gsonVersion"
|
||||||
implementation "commons-codec:commons-codec:$codecVersion"
|
implementation "commons-codec:commons-codec:$codecVersion"
|
||||||
implementation "org.apache.httpcomponents:httpcore:$httpcoreVersion"
|
implementation "org.apache.httpcomponents:httpcore:$httpcoreVersion"
|
||||||
@ -465,13 +469,18 @@ configure(project(':pricenode')) {
|
|||||||
exclude(module: 'commons-codec')
|
exclude(module: 'commons-codec')
|
||||||
}
|
}
|
||||||
compile("org.knowm.xchange:xchange-bitcoinaverage:$knowmXchangeVersion")
|
compile("org.knowm.xchange:xchange-bitcoinaverage:$knowmXchangeVersion")
|
||||||
|
compile("org.knowm.xchange:xchange-binance:$knowmXchangeVersion")
|
||||||
|
compile("org.knowm.xchange:xchange-bitfinex:$knowmXchangeVersion")
|
||||||
compile("org.knowm.xchange:xchange-coinmarketcap:$knowmXchangeVersion")
|
compile("org.knowm.xchange:xchange-coinmarketcap:$knowmXchangeVersion")
|
||||||
|
compile("org.knowm.xchange:xchange-kraken:$knowmXchangeVersion")
|
||||||
compile("org.knowm.xchange:xchange-poloniex:$knowmXchangeVersion")
|
compile("org.knowm.xchange:xchange-poloniex:$knowmXchangeVersion")
|
||||||
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
||||||
compile("org.springframework.boot:spring-boot-starter-actuator")
|
compile("org.springframework.boot:spring-boot-starter-actuator")
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
testCompile "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
testCompile "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
|
||||||
testRuntime("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
testRuntime("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion")
|
||||||
|
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||||
|
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
@ -19,9 +19,24 @@ package bisq.price.spot;
|
|||||||
|
|
||||||
import bisq.price.PriceProvider;
|
import bisq.price.PriceProvider;
|
||||||
|
|
||||||
|
import bisq.core.locale.CurrencyUtil;
|
||||||
|
import bisq.core.locale.TradeCurrency;
|
||||||
|
|
||||||
|
import org.knowm.xchange.Exchange;
|
||||||
|
import org.knowm.xchange.ExchangeFactory;
|
||||||
|
import org.knowm.xchange.currency.Currency;
|
||||||
|
import org.knowm.xchange.currency.CurrencyPair;
|
||||||
|
import org.knowm.xchange.dto.marketdata.Ticker;
|
||||||
|
import org.knowm.xchange.exceptions.CurrencyPairNotValidException;
|
||||||
|
import org.knowm.xchange.service.marketdata.MarketDataService;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for providers of bitcoin {@link ExchangeRate} data. Implementations
|
* Abstract base class for providers of bitcoin {@link ExchangeRate} data. Implementations
|
||||||
@ -60,4 +75,82 @@ public abstract class ExchangeRateProvider extends PriceProvider<Set<ExchangeRat
|
|||||||
.filter(e -> "USD".equals(e.getCurrency()) || "LTC".equals(e.getCurrency()))
|
.filter(e -> "USD".equals(e.getCurrency()) || "LTC".equals(e.getCurrency()))
|
||||||
.forEach(e -> log.info("BTC/{}: {}", e.getCurrency(), e.getPrice()));
|
.forEach(e -> log.info("BTC/{}: {}", e.getCurrency(), e.getPrice()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param exchangeClass Class of the {@link Exchange} for which the rates should be polled
|
||||||
|
* @return Exchange rates for Bisq-supported fiat currencies and altcoins in the specified {@link Exchange}
|
||||||
|
*
|
||||||
|
* @see CurrencyUtil#getAllSortedFiatCurrencies()
|
||||||
|
* @see CurrencyUtil#getAllSortedCryptoCurrencies()
|
||||||
|
*/
|
||||||
|
protected Set<ExchangeRate> doGet(Class<? extends Exchange> exchangeClass) {
|
||||||
|
Set<ExchangeRate> result = new HashSet<ExchangeRate>();
|
||||||
|
|
||||||
|
// Initialize XChange objects
|
||||||
|
Exchange exchange = ExchangeFactory.INSTANCE.createExchange(exchangeClass.getName());
|
||||||
|
MarketDataService marketDataService = exchange.getMarketDataService();
|
||||||
|
|
||||||
|
// Retrieve all currency pairs supported by the exchange
|
||||||
|
List<CurrencyPair> currencyPairs = exchange.getExchangeSymbols();
|
||||||
|
|
||||||
|
Set<String> supportedCryptoCurrencies = CurrencyUtil.getAllSortedCryptoCurrencies().stream()
|
||||||
|
.map(TradeCurrency::getCode)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<String> supportedFiatCurrencies = CurrencyUtil.getAllSortedFiatCurrencies().stream()
|
||||||
|
.map(TradeCurrency::getCode)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// Filter the supported fiat currencies (currency pair format is BTC-FIAT)
|
||||||
|
currencyPairs.stream()
|
||||||
|
.filter(cp -> cp.base.equals(Currency.BTC))
|
||||||
|
.filter(cp -> supportedFiatCurrencies.contains(cp.counter.getCurrencyCode()))
|
||||||
|
.forEach(cp -> {
|
||||||
|
try {
|
||||||
|
Ticker t = marketDataService.getTicker(new CurrencyPair(cp.base, cp.counter));
|
||||||
|
|
||||||
|
result.add(new ExchangeRate(
|
||||||
|
cp.counter.getCurrencyCode(),
|
||||||
|
t.getLast(),
|
||||||
|
// Some exchanges do not provide timestamps
|
||||||
|
t.getTimestamp() == null ? new Date() : t.getTimestamp(),
|
||||||
|
this.getName()
|
||||||
|
));
|
||||||
|
} catch (CurrencyPairNotValidException cpnve) {
|
||||||
|
// Some exchanges support certain currency pairs for other services but not for spot markets
|
||||||
|
// In that case, trying to retrieve the market ticker for that pair may fail with this specific type of exception
|
||||||
|
log.info("Currency pair " + cp + " not supported in Spot Markets: " + cpnve.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Catch any other type of generic exception (IO, network level, rate limit reached, etc)
|
||||||
|
log.info("Exception encountered while retrieving rate for currency pair " + cp + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter the supported altcoins (currency pair format is ALT-BTC)
|
||||||
|
currencyPairs.stream()
|
||||||
|
.filter(cp -> cp.counter.equals(Currency.BTC))
|
||||||
|
.filter(cp -> supportedCryptoCurrencies.contains(cp.base.getCurrencyCode()))
|
||||||
|
.forEach(cp -> {
|
||||||
|
try {
|
||||||
|
Ticker t = marketDataService.getTicker(new CurrencyPair(cp.base, cp.counter));
|
||||||
|
|
||||||
|
result.add(new ExchangeRate(
|
||||||
|
cp.base.getCurrencyCode(),
|
||||||
|
t.getLast(),
|
||||||
|
// Some exchanges do not provide timestamps
|
||||||
|
t.getTimestamp() == null ? new Date() : t.getTimestamp(),
|
||||||
|
this.getName()
|
||||||
|
));
|
||||||
|
} catch (CurrencyPairNotValidException cpnve) {
|
||||||
|
// Some exchanges support certain currency pairs for other services but not for spot markets
|
||||||
|
// In that case, trying to retrieve the market ticker for that pair may fail with this specific type of exception
|
||||||
|
log.info("Currency pair " + cp + " not supported in Spot Markets: " + cpnve.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Catch any other type of generic exception (IO, network level, rate limit reached, etc)
|
||||||
|
log.info("Exception encountered while retrieving rate for currency pair " + cp + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.spot.ExchangeRate;
|
||||||
|
import bisq.price.spot.ExchangeRateProvider;
|
||||||
|
|
||||||
|
import org.knowm.xchange.binance.BinanceExchange;
|
||||||
|
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Order(5)
|
||||||
|
public class Binance extends ExchangeRateProvider {
|
||||||
|
|
||||||
|
public Binance() {
|
||||||
|
super("BINANCE", "binance", Duration.ofMinutes(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ExchangeRate> doGet() {
|
||||||
|
// Supported fiat: EUR, NGN, RUB, TRY, ZAR
|
||||||
|
// Supported alts: BEAM, DASH, DCR, DOGE, ETC, ETH, LTC, NAV, PIVX, XMR, XZC, ZEC, ZEN
|
||||||
|
return doGet(BinanceExchange.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.spot.ExchangeRate;
|
||||||
|
import bisq.price.spot.ExchangeRateProvider;
|
||||||
|
|
||||||
|
import org.knowm.xchange.bitfinex.BitfinexExchange;
|
||||||
|
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Order(6)
|
||||||
|
public class Bitfinex extends ExchangeRateProvider {
|
||||||
|
|
||||||
|
public Bitfinex() {
|
||||||
|
super("BITFINEX", "bitfinex", Duration.ofMinutes(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ExchangeRate> doGet() {
|
||||||
|
// Supported fiat: EUR, GBP, JPY, USD
|
||||||
|
// Supported alts: DAI, ETC, ETH, LTC, XMR, ZEC
|
||||||
|
return doGet(BitfinexExchange.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.spot.ExchangeRate;
|
||||||
|
import bisq.price.spot.ExchangeRateProvider;
|
||||||
|
|
||||||
|
import org.knowm.xchange.kraken.KrakenExchange;
|
||||||
|
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Order(7)
|
||||||
|
public class Kraken extends ExchangeRateProvider {
|
||||||
|
|
||||||
|
public Kraken() {
|
||||||
|
super("KRAKEN", "kraken", Duration.ofMinutes(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ExchangeRate> doGet() {
|
||||||
|
// Supported fiat: AUD, CAD, CHF, EUR, GBP, JPY, USD
|
||||||
|
// Supported alts: DASH, DOGE, ETC, ETH, LTC, XMR, ZEC
|
||||||
|
return doGet(KrakenExchange.class);
|
||||||
|
}
|
||||||
|
}
|
@ -19,33 +19,19 @@ package bisq.price.spot.providers;
|
|||||||
|
|
||||||
import bisq.price.spot.ExchangeRate;
|
import bisq.price.spot.ExchangeRate;
|
||||||
import bisq.price.spot.ExchangeRateProvider;
|
import bisq.price.spot.ExchangeRateProvider;
|
||||||
import bisq.price.util.Altcoins;
|
|
||||||
|
|
||||||
import org.knowm.xchange.currency.Currency;
|
import org.knowm.xchange.poloniex.PoloniexExchange;
|
||||||
import org.knowm.xchange.currency.CurrencyPair;
|
|
||||||
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexMarketData;
|
|
||||||
import org.knowm.xchange.poloniex.dto.marketdata.PoloniexTicker;
|
|
||||||
|
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.http.RequestEntity;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Order(4)
|
@Order(4)
|
||||||
class Poloniex extends ExchangeRateProvider {
|
public class Poloniex extends ExchangeRateProvider {
|
||||||
|
|
||||||
private final RestTemplate restTemplate = new RestTemplate();
|
|
||||||
|
|
||||||
public Poloniex() {
|
public Poloniex() {
|
||||||
super("POLO", "poloniex", Duration.ofMinutes(1));
|
super("POLO", "poloniex", Duration.ofMinutes(1));
|
||||||
@ -53,42 +39,8 @@ class Poloniex extends ExchangeRateProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ExchangeRate> doGet() {
|
public Set<ExchangeRate> doGet() {
|
||||||
Date timestamp = new Date(); // Poloniex tickers don't include their own timestamp
|
// Supported fiat: -
|
||||||
|
// Supported alts: DASH, DCR, DOGE, ETC, ETH, GRIN, LTC, XMR, ZEC
|
||||||
return getTickers()
|
return doGet(PoloniexExchange.class);
|
||||||
.filter(t -> t.getCurrencyPair().base.equals(Currency.BTC))
|
|
||||||
.filter(t -> Altcoins.ALL_SUPPORTED.contains(t.getCurrencyPair().counter.getCurrencyCode()))
|
|
||||||
.map(t ->
|
|
||||||
new ExchangeRate(
|
|
||||||
t.getCurrencyPair().counter.getCurrencyCode(),
|
|
||||||
t.getPoloniexMarketData().getLast(),
|
|
||||||
timestamp,
|
|
||||||
this.getName()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Stream<PoloniexTicker> getTickers() {
|
|
||||||
|
|
||||||
return getTickersKeyedByCurrencyPair().entrySet().stream()
|
|
||||||
.map(e -> {
|
|
||||||
String pair = e.getKey();
|
|
||||||
PoloniexMarketData data = e.getValue();
|
|
||||||
String[] symbols = pair.split("_"); // e.g. BTC_USD => [BTC, USD]
|
|
||||||
return new PoloniexTicker(data, new CurrencyPair(symbols[0], symbols[1]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, PoloniexMarketData> getTickersKeyedByCurrencyPair() {
|
|
||||||
return restTemplate.exchange(
|
|
||||||
RequestEntity
|
|
||||||
.get(UriComponentsBuilder
|
|
||||||
.fromUriString("https://poloniex.com/public?command=returnTicker").build()
|
|
||||||
.toUri())
|
|
||||||
.build(),
|
|
||||||
new ParameterizedTypeReference<Map<String, PoloniexMarketData>>() {
|
|
||||||
}
|
|
||||||
).getBody();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
74
pricenode/src/test/java/bisq/price/ExchangeTestBase.java
Normal file
74
pricenode/src/test/java/bisq/price/ExchangeTestBase.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package bisq.price;
|
||||||
|
|
||||||
|
import bisq.price.spot.ExchangeRate;
|
||||||
|
import bisq.price.spot.ExchangeRateProvider;
|
||||||
|
|
||||||
|
import bisq.core.locale.CurrencyUtil;
|
||||||
|
import bisq.core.locale.TradeCurrency;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ExchangeTestBase {
|
||||||
|
|
||||||
|
protected void doGet_successfulCall(ExchangeRateProvider exchangeProvider) {
|
||||||
|
|
||||||
|
// Use the XChange library to call the provider API, in order to retrieve the
|
||||||
|
// exchange rates. If the API call fails, or the response body cannot be parsed,
|
||||||
|
// the test will fail with an exception
|
||||||
|
Set<ExchangeRate> retrievedExchangeRates = exchangeProvider.doGet();
|
||||||
|
|
||||||
|
// Log the valid exchange rates which were retrieved
|
||||||
|
// Useful when running the tests, to easily identify which exchanges provide useful pairs
|
||||||
|
retrievedExchangeRates.forEach(e -> log.info("Found exchange rate " + e.toString()));
|
||||||
|
|
||||||
|
// Sanity checks
|
||||||
|
assertTrue(retrievedExchangeRates.size() > 0);
|
||||||
|
checkProviderCurrencyPairs(retrievedExchangeRates);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that every retrieved currency pair is between BTC and either
|
||||||
|
* A) a fiat currency on the list of Bisq-supported fiat currencies, or
|
||||||
|
* B) an altcoin on the list of Bisq-supported altcoins
|
||||||
|
*
|
||||||
|
* @param retrievedExchangeRates Exchange rates retrieved from the provider
|
||||||
|
*/
|
||||||
|
private void checkProviderCurrencyPairs(Set<ExchangeRate> retrievedExchangeRates) {
|
||||||
|
Set<String> retrievedRatesCurrencies = retrievedExchangeRates.stream()
|
||||||
|
.map(ExchangeRate::getCurrency)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<String> supportedCryptoCurrencies = CurrencyUtil.getAllSortedCryptoCurrencies().stream()
|
||||||
|
.map(TradeCurrency::getCode)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<String> supportedFiatCurrencies = CurrencyUtil.getAllSortedFiatCurrencies().stream()
|
||||||
|
.map(TradeCurrency::getCode)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<String> supportedFiatCurrenciesRetrieved = supportedFiatCurrencies.stream()
|
||||||
|
.filter(f -> retrievedRatesCurrencies.contains(f))
|
||||||
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
|
log.info("Retrieved rates for supported fiat currencies: " + supportedFiatCurrenciesRetrieved);
|
||||||
|
|
||||||
|
Set<String> supportedCryptoCurrenciesRetrieved = supportedCryptoCurrencies.stream()
|
||||||
|
.filter(c -> retrievedRatesCurrencies.contains(c))
|
||||||
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
|
log.info("Retrieved rates for supported altcoins: " + supportedCryptoCurrenciesRetrieved);
|
||||||
|
|
||||||
|
Set<String> supportedCurrencies = Sets.union(supportedCryptoCurrencies, supportedFiatCurrencies);
|
||||||
|
|
||||||
|
Set unsupportedCurrencies = Sets.difference(retrievedRatesCurrencies, supportedCurrencies);
|
||||||
|
assertTrue("Retrieved exchange rates contain unsupported currencies: " + unsupportedCurrencies,
|
||||||
|
unsupportedCurrencies.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.ExchangeTestBase;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class BinanceTest extends ExchangeTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doGet_successfulCall() {
|
||||||
|
doGet_successfulCall(new Binance());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.ExchangeTestBase;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class BitfinexTest extends ExchangeTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doGet_successfulCall() {
|
||||||
|
doGet_successfulCall(new Bitfinex());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.ExchangeTestBase;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class KrakenTest extends ExchangeTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doGet_successfulCall() {
|
||||||
|
doGet_successfulCall(new Kraken());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Bisq.
|
||||||
|
*
|
||||||
|
* Bisq is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bisq.price.spot.providers;
|
||||||
|
|
||||||
|
import bisq.price.ExchangeTestBase;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class PoloniexTest extends ExchangeTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doGet_successfulCall() {
|
||||||
|
doGet_successfulCall(new Poloniex());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user