mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-01 10:07:02 -04:00
Add market price feed for altcoins
This commit is contained in:
parent
d2e8c6afd7
commit
eefafab977
14 changed files with 177 additions and 63 deletions
|
@ -13,10 +13,21 @@ public class MarketPrice {
|
|||
private final double last;
|
||||
|
||||
public MarketPrice(String currencyCode, String ask, String bid, String last) {
|
||||
this(currencyCode, ask, bid, last, false);
|
||||
}
|
||||
|
||||
public MarketPrice(String currencyCode, String ask, String bid, String last, boolean invert) {
|
||||
this.currencyCode = currencyCode;
|
||||
this.ask = parseDouble(ask);
|
||||
this.bid = parseDouble(bid);
|
||||
this.last = parseDouble(last);
|
||||
if (invert) {
|
||||
this.ask = 1d / parseDouble(ask);
|
||||
this.bid = 1d / parseDouble(bid);
|
||||
this.last = 1d / parseDouble(last);
|
||||
} else {
|
||||
this.ask = parseDouble(ask);
|
||||
this.bid = parseDouble(bid);
|
||||
this.last = parseDouble(last);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public double getPrice(MarketPriceFeed.Type type) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.google.common.util.concurrent.SettableFuture;
|
|||
import com.google.inject.Inject;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.pricefeed.providers.BitcoinAveragePriceProvider;
|
||||
import io.bitsquare.btc.pricefeed.providers.PoloniexPriceProvider;
|
||||
import io.bitsquare.btc.pricefeed.providers.PriceProvider;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.FaultHandler;
|
||||
|
@ -18,6 +19,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
@ -43,15 +45,15 @@ public class MarketPriceFeed {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// https://poloniex.com/public?command=returnTicker 33 kb
|
||||
private static long PERIOD = 30;
|
||||
private static long PERIOD_FIAT = 1; // We load only the selected currency on interval. Only the first request we load all
|
||||
private static long PERIOD_CRYPTO = 10; // We load the full list with 33kb so we don't want to load too often
|
||||
|
||||
private final ScheduledThreadPoolExecutor executorService = Utilities.getScheduledThreadPoolExecutor("MarketPriceFeed", 5, 10, 120L);
|
||||
private final ScheduledThreadPoolExecutor executorService = Utilities.getScheduledThreadPoolExecutor("MarketPriceFeed", 5, 10, 700L);
|
||||
private final Map<String, MarketPrice> cache = new HashMap<>();
|
||||
private final PriceProvider fiatPriceProvider = new BitcoinAveragePriceProvider();
|
||||
private final PriceProvider cryptoCurrenciesPriceProvider = new PoloniexPriceProvider();
|
||||
private Consumer<Double> priceConsumer;
|
||||
private FaultHandler faultHandler;
|
||||
private PriceProvider fiatPriceProvider = new BitcoinAveragePriceProvider();
|
||||
private Type type;
|
||||
private String currencyCode;
|
||||
transient private final StringProperty currencyCodeProperty = new SimpleStringProperty();
|
||||
|
@ -66,6 +68,7 @@ public class MarketPriceFeed {
|
|||
public MarketPriceFeed() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -76,8 +79,18 @@ public class MarketPriceFeed {
|
|||
|
||||
requestAllPrices(fiatPriceProvider, () -> {
|
||||
applyPrice();
|
||||
executorService.scheduleAtFixedRate(() -> requestPrice(fiatPriceProvider), PERIOD, PERIOD, TimeUnit.SECONDS);
|
||||
executorService.scheduleAtFixedRate(
|
||||
() -> requestPrice(fiatPriceProvider),
|
||||
PERIOD_FIAT, PERIOD_FIAT, TimeUnit.MINUTES);
|
||||
});
|
||||
requestAllPrices(cryptoCurrenciesPriceProvider, () -> {
|
||||
applyPrice();
|
||||
executorService.scheduleAtFixedRate(
|
||||
() -> requestAllPrices(cryptoCurrenciesPriceProvider,
|
||||
this::applyPrice),
|
||||
PERIOD_CRYPTO, PERIOD_CRYPTO, TimeUnit.MINUTES);
|
||||
});
|
||||
requestAllPrices(cryptoCurrenciesPriceProvider, this::applyPrice);
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,7 +169,7 @@ public class MarketPriceFeed {
|
|||
});
|
||||
}
|
||||
|
||||
private void requestAllPrices(PriceProvider provider, Runnable resultHandler) {
|
||||
private void requestAllPrices(PriceProvider provider, @Nullable Runnable resultHandler) {
|
||||
Log.traceCall();
|
||||
GetPriceRequest getPriceRequest = new GetPriceRequest();
|
||||
SettableFuture<Map<String, MarketPrice>> future = getPriceRequest.requestAllPrices(provider);
|
||||
|
@ -164,7 +177,8 @@ public class MarketPriceFeed {
|
|||
public void onSuccess(Map<String, MarketPrice> marketPriceMap) {
|
||||
UserThread.execute(() -> {
|
||||
cache.putAll(marketPriceMap);
|
||||
resultHandler.run();
|
||||
if (resultHandler != null)
|
||||
resultHandler.run();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package io.bitsquare.btc.pricefeed.providers;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.internal.LinkedTreeMap;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.pricefeed.MarketPrice;
|
||||
import io.bitsquare.http.HttpClient;
|
||||
import io.bitsquare.http.HttpException;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PoloniexPriceProvider implements PriceProvider {
|
||||
private static final Logger log = LoggerFactory.getLogger(PoloniexPriceProvider.class);
|
||||
|
||||
//https://poloniex.com/public?command=returnTicker
|
||||
private final HttpClient httpClient = new HttpClient("https://poloniex.com/public");
|
||||
|
||||
public PoloniexPriceProvider() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, MarketPrice> getAllPrices() throws IOException, HttpException {
|
||||
Map<String, MarketPrice> marketPriceMap = new HashMap<>();
|
||||
String response = httpClient.requestWithGET("?command=returnTicker");
|
||||
LinkedTreeMap<String, Object> treeMap = new Gson().fromJson(response, LinkedTreeMap.class);
|
||||
Map<String, String> temp = new HashMap<>();
|
||||
Set<String> supported = CurrencyUtil.getSortedCryptoCurrencies().stream()
|
||||
.map(TradeCurrency::getCode)
|
||||
.collect(Collectors.toSet());
|
||||
treeMap.entrySet().stream().forEach(e -> {
|
||||
Object value = e.getValue();
|
||||
String currencyPair = e.getKey();
|
||||
String otherCurrency = null;
|
||||
if (currencyPair.startsWith("BTC")) {
|
||||
String[] tokens = currencyPair.split("_");
|
||||
if (tokens.length > 1) {
|
||||
otherCurrency = tokens[1];
|
||||
if (supported.contains(otherCurrency)) {
|
||||
if (value instanceof LinkedTreeMap) {
|
||||
LinkedTreeMap<String, Object> treeMap2 = (LinkedTreeMap) value;
|
||||
temp.clear();
|
||||
treeMap2.entrySet().stream().forEach(e2 -> temp.put(e2.getKey(), e2.getValue().toString()));
|
||||
marketPriceMap.put(otherCurrency,
|
||||
new MarketPrice(otherCurrency, temp.get("lowestAsk"), temp.get("highestBid"), temp.get("last"), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return marketPriceMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MarketPrice getPrice(String currencyCode) throws IOException, HttpException {
|
||||
Log.traceCall("currencyCode=" + currencyCode);
|
||||
JsonObject jsonObject = new JsonParser()
|
||||
.parse(httpClient.requestWithGET(currencyCode))
|
||||
.getAsJsonObject();
|
||||
return new MarketPrice(currencyCode,
|
||||
jsonObject.get("ask").getAsString(),
|
||||
jsonObject.get("bid").getAsString(),
|
||||
jsonObject.get("last").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BitcoinAveragePriceProvider{" +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -178,20 +178,20 @@ public class CurrencyUtil {
|
|||
// result.add(new CryptoCurrency("XMR", "Monero"));
|
||||
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
|
||||
result.add(new CryptoCurrency("DASH", "Dash"));
|
||||
result.add(new CryptoCurrency("ANC", "Anoncoin"));
|
||||
result.add(new CryptoCurrency("NBT", "NuBits"));
|
||||
result.add(new CryptoCurrency("NSR", "NuShares"));
|
||||
result.add(new CryptoCurrency("FAIR", "FairCoin"));
|
||||
result.add(new CryptoCurrency("PPC", "Peercoin"));
|
||||
result.add(new CryptoCurrency("XPM", "Primecoin"));
|
||||
result.add(new CryptoCurrency("SC", "Siacoin"));
|
||||
result.add(new CryptoCurrency("SJCX", "StorjcoinX"));
|
||||
result.add(new CryptoCurrency("GEMZ", "Gemz"));
|
||||
result.add(new CryptoCurrency("DOGE", "Dogecoin"));
|
||||
result.add(new CryptoCurrency("BLK", "Blackcoin"));
|
||||
result.add(new CryptoCurrency("FCT", "Factom"));
|
||||
result.add(new CryptoCurrency("NXT", "Nxt"));
|
||||
result.add(new CryptoCurrency("BTS", "BitShares"));
|
||||
result.add(new CryptoCurrency("XCP", "Counterparty"));
|
||||
result.add(new CryptoCurrency("XRP", "Ripple"));
|
||||
// Stellar (XLM Lumen) uses an additional memo field. We dont support that for now
|
||||
//result.add(new CryptoCurrency("STR", "Stellar"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue