Skip to content

Commit

Permalink
Merge pull request #30 from alvasw/cryptoya_create_exchange_rate_per_…
Browse files Browse the repository at this point in the history
…exchange

CryptoYa: Create ExchangeRate per exchange
  • Loading branch information
gabernard authored Sep 18, 2023
2 parents 806cdbf + 8068ce7 commit 8c8148a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 115 deletions.
2 changes: 1 addition & 1 deletion src/main/java/bisq/price/spot/ExchangeRateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ private Map<String, Object> getMetadata(ExchangeRateProvider provider) {

private long getTimestamp(ExchangeRateProvider provider, Set<ExchangeRate> exchangeRates) {
return exchangeRates.stream()
.filter(e -> provider.getName().equals(e.getProvider()))
.filter(e -> e.getProvider().startsWith(provider.getName()))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No exchange rate data found for " + provider.getName()))
.getTimestamp();
Expand Down
50 changes: 30 additions & 20 deletions src/main/java/bisq/price/spot/providers/CryptoYa.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@

import bisq.price.spot.ExchangeRate;
import bisq.price.spot.ExchangeRateProvider;
import bisq.price.util.cryptoya.CryptoYaMarketData;
import bisq.price.util.cryptoya.CryptoYaTicker;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.OptionalDouble;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* CryptoYa is used only for Argentina Peso (ARS).
Expand All @@ -39,44 +41,52 @@
* This ExchangeRateProvider provides a real market rate (black or "blue") for ARS/BTC
*/
@Component
class CryptoYa extends ExchangeRateProvider implements BlueRateProvider {
public class CryptoYa extends ExchangeRateProvider implements BlueRateProvider {

public static final String PROVIDER_NAME = "CRYPTOYA";
private static final String CRYPTO_YA_BTC_ARS_API_URL = "https://criptoya.com/api/btc/ars/0.1";

private final WebClient webClient = WebClient.create();

public CryptoYa(Environment env) {
super(env, "CRYPTOYA", "cryptoya", Duration.ofMinutes(1));
super(env, PROVIDER_NAME, "cryptoya", Duration.ofMinutes(1));
}

/**
*
* @return average price buy/sell price averaging different providers suported by cryptoya api
* which uses the free market (or blue, or unofficial) ARS price for BTC
*/
@Override
public Set<ExchangeRate> doGet() {
CryptoYaMarketData cryptoYaMarketData = fetchArsBlueMarketData();
OptionalDouble arsBlueRate = cryptoYaMarketData.averagedArsBlueRateFromLast24Hours();
Map<String, CryptoYaTicker> cryptoYaMarketData = fetchArsBlueMarketData();

if (arsBlueRate.isPresent()) {
ExchangeRate exchangeRate = new ExchangeRate(
"ARS",
arsBlueRate.getAsDouble(),
System.currentTimeMillis(),
this.getName());
return Set.of(exchangeRate);
}
Instant yesterdayInstant = Instant.now()
.minus(1, ChronoUnit.DAYS);

return Collections.emptySet();
return cryptoYaMarketData.entrySet()
.stream()
.map(cryptoYaEntryToExchangeRate(yesterdayInstant))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toUnmodifiableSet());
}

private CryptoYaMarketData fetchArsBlueMarketData() {
private Map<String, CryptoYaTicker> fetchArsBlueMarketData() {
return webClient.get()
.uri(CRYPTO_YA_BTC_ARS_API_URL)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(CryptoYaMarketData.class)
.bodyToMono(new ParameterizedTypeReference<Map<String, CryptoYaTicker>>() {
})
.block(Duration.of(30, ChronoUnit.SECONDS));
}

private Function<Map.Entry<String, CryptoYaTicker>, Optional<ExchangeRate>> cryptoYaEntryToExchangeRate(
Instant newerThanInstant) {
return entry -> {
String exchangeName = entry.getKey();
CryptoYaTicker ticker = entry.getValue();
return ticker.toExchangeRate(exchangeName, newerThanInstant);
};
}
}
92 changes: 0 additions & 92 deletions src/main/java/bisq/price/util/cryptoya/CryptoYaMarketData.java

This file was deleted.

29 changes: 27 additions & 2 deletions src/main/java/bisq/price/util/cryptoya/CryptoYaTicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,46 @@

package bisq.price.util.cryptoya;

import bisq.price.spot.ExchangeRate;
import bisq.price.spot.providers.CryptoYa;
import lombok.Getter;
import lombok.Setter;

import java.time.Instant;
import java.util.Optional;

@Getter
@Setter
public class CryptoYaTicker {

private double ask;

private double totalAsk;

private double bid;

private double totalBid;

private long time;

public Optional<ExchangeRate> toExchangeRate(String exchangeName, Instant newerThan) {
if (isTooOld(newerThan) || isAskZeroOrNegative()) {
return Optional.empty();
}

return Optional.of(
new ExchangeRate(
"ARS",
ask,
System.currentTimeMillis(),
CryptoYa.PROVIDER_NAME + ": " + exchangeName
)
);
}

private boolean isTooOld(Instant newerThan) {
return time <= newerThan.getEpochSecond();
}

private boolean isAskZeroOrNegative() {
return ask <= 0;
}
}

0 comments on commit 8c8148a

Please sign in to comment.