org.knowm.xchange.BaseExchange Maven / Gradle / Ivy
package org.knowm.xchange;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.meta.ExchangeMetaData;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.service.BaseExchangeService;
import org.knowm.xchange.service.account.AccountService;
import org.knowm.xchange.service.marketdata.MarketDataService;
import org.knowm.xchange.service.trade.TradeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class BaseExchange implements Exchange {
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected ExchangeSpecification exchangeSpecification;
protected ExchangeMetaData exchangeMetaData;
protected MarketDataService marketDataService;
protected TradeService tradeService;
protected AccountService accountService;
protected abstract void initServices();
@Override
public void applySpecification(ExchangeSpecification exchangeSpecification) {
ExchangeSpecification defaultSpecification = getDefaultExchangeSpecification();
// Check if default is for everything
if (exchangeSpecification == null) {
this.exchangeSpecification = defaultSpecification;
} else {
// Using a configured exchange
// fill in null params with the default ones
if (exchangeSpecification.getExchangeName() == null) {
exchangeSpecification.setExchangeName(defaultSpecification.getExchangeName());
}
if (exchangeSpecification.getExchangeDescription() == null) {
exchangeSpecification.setExchangeDescription(defaultSpecification.getExchangeDescription());
}
if (exchangeSpecification.getSslUri() == null) {
exchangeSpecification.setSslUri(defaultSpecification.getSslUri());
}
if (exchangeSpecification.getHost() == null) {
exchangeSpecification.setHost(defaultSpecification.getHost());
}
if (exchangeSpecification.getPlainTextUri() == null) {
exchangeSpecification.setPlainTextUri(defaultSpecification.getPlainTextUri());
}
if (exchangeSpecification.getExchangeSpecificParameters() == null) {
exchangeSpecification.setExchangeSpecificParameters(
defaultSpecification.getExchangeSpecificParameters());
} else {
// add default value unless it is overridden by current spec
for (Map.Entry entry :
defaultSpecification.getExchangeSpecificParameters().entrySet()) {
if (exchangeSpecification.getExchangeSpecificParametersItem(entry.getKey()) == null) {
exchangeSpecification.setExchangeSpecificParametersItem(
entry.getKey(), entry.getValue());
}
}
}
this.exchangeSpecification = exchangeSpecification;
}
if (this.exchangeSpecification.getMetaDataJsonFileOverride()
!= null) { // load the metadata from the file system
try (InputStream is =
new FileInputStream(this.exchangeSpecification.getMetaDataJsonFileOverride())) {
loadExchangeMetaData(is);
} catch (IOException e) {
throw new ExchangeException(e);
}
} else if (this.exchangeSpecification.getExchangeName()
!= null) { // load the metadata from the classpath
try (InputStream is =
BaseExchangeService.class
.getClassLoader()
.getResourceAsStream(getMetaDataFileName(this.exchangeSpecification) + ".json")) {
loadExchangeMetaData(is);
} catch (IOException e) {
throw new ExchangeException(e);
}
} else {
logger.warn(
"No \"exchange name\" found in the ExchangeSpecification. The name is used to load the meta data file from the classpath and may lead to unexpected results.");
}
initServices();
if (this.exchangeSpecification.isShouldLoadRemoteMetaData()) {
try {
logger.info("Calling Remote Init...");
remoteInit();
} catch (IOException e) {
throw new ExchangeException(e);
}
}
}
@Override
public void remoteInit() throws IOException, ExchangeException {
logger.info(
"No remote initialization implemented for {}. The exchange meta data for this exchange is loaded from a json file containing hard-coded exchange meta-data. This may or may not be OK for you, and you should understand exactly how this works. Each exchange can either 1) rely on the hard-coded json file that comes packaged with XChange's jar, 2) provide your own override json file, 3) properly implement the `remoteInit()` method for the exchange (please submit a pull request so the whole community can benefit) or 4) a combination of hard-coded JSON and remote API calls. For more info see: https://github.com/timmolter/XChange/wiki/Design-Notes#exchange-metadata",
exchangeSpecification.getExchangeName());
}
protected void loadExchangeMetaData(InputStream is) {
exchangeMetaData = loadMetaData(is, ExchangeMetaData.class);
}
protected T loadMetaData(InputStream is, Class type) {
// Use Jackson to parse it
ObjectMapper mapper = new ObjectMapper();
try {
T result = mapper.readValue(is, type);
logger.debug(result.toString());
return result;
} catch (Exception e) {
logger.warn(
"An exception occured while loading the metadata file from the file system. This is just a warning and can be ignored, but it may lead to unexpected results, so it's better to address it.",
e);
return null;
}
}
@Override
public List getExchangeSymbols() {
return new ArrayList<>(getExchangeMetaData().getCurrencyPairs().keySet());
}
public String getMetaDataFileName(ExchangeSpecification exchangeSpecification) {
return exchangeSpecification
.getExchangeName()
.toLowerCase()
.replace(" ", "")
.replace("-", "")
.replace(".", "");
}
@Override
public ExchangeSpecification getExchangeSpecification() {
return exchangeSpecification;
}
@Override
public ExchangeMetaData getExchangeMetaData() {
return exchangeMetaData;
}
public MarketDataService getMarketDataService() {
return marketDataService;
}
public TradeService getTradeService() {
return tradeService;
}
public AccountService getAccountService() {
return accountService;
}
@Override
public String toString() {
String name =
exchangeSpecification != null
? exchangeSpecification.getExchangeName()
: getClass().getName();
return name + "#" + hashCode();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy