package org.knowm.xchange.ripple;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.knowm.xchange.BaseExchange;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.ripple.service.RippleAccountService;
import org.knowm.xchange.ripple.service.RippleMarketDataService;
import org.knowm.xchange.ripple.service.RippleTradeService;
import org.knowm.xchange.utils.nonce.CurrentTimeNonceFactory;
import si.mazi.rescu.SynchronizedValueFactory;
public class RippleExchange extends BaseExchange implements Exchange {
public static final String REST_API_RIPPLE_LABS = "https://api.ripple.com/";
public static final String REST_API_LOCALHOST_PLAIN_TEXT = "http://localhost:5990/";
private static final String README = "https://github.com/timmolter/XChange/tree/develop/xchange-ripple";
public static final String PARAMETER_TRUST_API_RIPPLE_COM = "trust.api.ripple.com";
public static final String PARAMETER_STORE_TRADE_TRANSACTION_DETAILS = "store.trade.transaction.details";
public static final String PARAMETER_VALIDATE_ORDER_REQUESTS = "validate.order.requests";
public static final String PARAMETER_ROUNDING_SCALE = "rounding.scale";
public static final int DEFAULT_ROUNDING_SCALE = 50;
private final SynchronizedValueFactory<Long> nonceFactory = new CurrentTimeNonceFactory();
@Override
public void applySpecification(final ExchangeSpecification specification) {
super.applySpecification(specification);
if ((specification.getSecretKey() != null) && (specification.getSecretKey().length() > 0)
&& specification.getSslUri().equals(REST_API_RIPPLE_LABS)
&& (Boolean.parseBoolean(specification.getParameter(PARAMETER_TRUST_API_RIPPLE_COM).toString()) == false)) {
throw new IllegalStateException(String.format("server %s has not been trusted - see %s for details", REST_API_RIPPLE_LABS, README));
}
}
@Override
protected void initServices() {
marketDataService = new RippleMarketDataService(this);
tradeService = new RippleTradeService(this);
accountService = new RippleAccountService(this);
}
@Override
public ExchangeSpecification getDefaultExchangeSpecification() {
final ExchangeSpecification specification = new ExchangeSpecification(this.getClass().getCanonicalName());
specification.setSslUri(REST_API_RIPPLE_LABS);
specification.setExchangeName("Ripple");
specification.setExchangeDescription("Ripple is a payment system, currency exchange and remittance network");
// By default only use https://api.ripple.com/ for queries that do not require authentication, i.e. do not send secret key to Ripple labs servers.
specification.setExchangeSpecificParametersItem(PARAMETER_TRUST_API_RIPPLE_COM, false);
// Do not cache order detail queries by default to avoid running out of memory
specification.setExchangeSpecificParametersItem(PARAMETER_STORE_TRADE_TRANSACTION_DETAILS, false);
// Wait for ledger consensus before confirming successful order entry or cancel
specification.setExchangeSpecificParametersItem(PARAMETER_VALIDATE_ORDER_REQUESTS, true);
// Round to this decimal places on BigDecimal division
specification.setExchangeSpecificParametersItem(PARAMETER_ROUNDING_SCALE, DEFAULT_ROUNDING_SCALE);
return specification;
}
@Override
public SynchronizedValueFactory<Long> getNonceFactory() {
return nonceFactory;
}
public int getRoundingScale() {
final ExchangeSpecification specification;
if (exchangeSpecification == null) {
specification = getDefaultExchangeSpecification();
} else {
specification = exchangeSpecification;
}
return (Integer) specification.getExchangeSpecificParametersItem(RippleExchange.PARAMETER_ROUNDING_SCALE);
}
public boolean validateOrderRequests() {
return (Boolean) getExchangeSpecification().getExchangeSpecificParametersItem(PARAMETER_VALIDATE_ORDER_REQUESTS);
}
public boolean isStoreTradeTransactionDetails() {
return (Boolean) getExchangeSpecification().getExchangeSpecificParametersItem(PARAMETER_STORE_TRADE_TRANSACTION_DETAILS);
}
public void clearOrderDetailsCache() {
((RippleTradeService) tradeService).clearOrderDetailsStore();
}
/**
* Converts a datetime string as returned from the Ripple REST API into a java date object. The string is the UTC time in format
* yyyy-MM-dd'T'hh:mm:ss.SSS'Z' e.g. 2015-06-13T11:45:20.102Z
*
* @throws ParseException
*/
public static Date ToDate(final String datetime) throws ParseException {
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
return format.parse(datetime);
}
}