Skip to content

Commit

Permalink
Converted BitfinexExchangeAdapter to take all config from exchange.xm…
Browse files Browse the repository at this point in the history
…l. Currently undergoing live testing with the exchange.

This commit is the 0.2-beta RC.

Stable versions of the bot can always be found on the Release page.
  • Loading branch information
gazbert committed Jul 15, 2016
1 parent fd50a08 commit aba511a
Show file tree
Hide file tree
Showing 17 changed files with 153 additions and 342 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ hs_err_pid*
/resources/okcoin/okcoin-config.properties
/resources/huobi/huobi-config.properties
/resources/itbit/itbit-config.properties
/resources/gdax/coinbase-config.properties
/resources/gdax/gdax-config.properties
/resources/kraken/kraken-config.properties
Binary file modified config/samples/bitfinex/email-alerts.xml
Binary file not shown.
Binary file modified config/samples/bitfinex/engine.xml
Binary file not shown.
Binary file modified config/samples/bitfinex/exchange.xml
Binary file not shown.
Binary file modified config/samples/bitfinex/markets.xml
Binary file not shown.
Binary file modified config/samples/bitfinex/strategies.xml
Binary file not shown.
Binary file modified config/samples/btce/markets.xml
Binary file not shown.
Binary file modified config/samples/gdax/markets.xml
Binary file not shown.
Binary file modified config/samples/huobi/markets.xml
Binary file not shown.
Binary file modified config/samples/okcoin/markets.xml
Binary file not shown.
32 changes: 0 additions & 32 deletions resources/bitfinex/bitfinex-config.properties.template

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

package com.gazbert.bxbot.core.exchanges;

import com.gazbert.bxbot.core.api.exchange.AuthenticationConfig;
import com.gazbert.bxbot.core.api.exchange.ExchangeAdapter;
import com.gazbert.bxbot.core.api.exchange.ExchangeConfig;
import com.gazbert.bxbot.core.api.trading.BalanceInfo;
import com.gazbert.bxbot.core.api.trading.ExchangeNetworkException;
import com.gazbert.bxbot.core.api.trading.MarketOrder;
Expand All @@ -40,8 +43,6 @@
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
Expand All @@ -57,7 +58,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
* <p>
Expand Down Expand Up @@ -99,7 +99,7 @@
*
* @author gazbert
*/
public final class BitfinexExchangeAdapter extends AbstractExchangeAdapter implements TradingApi {
public final class BitfinexExchangeAdapter extends AbstractExchangeAdapter implements ExchangeAdapter {

private static final Logger LOG = Logger.getLogger(BitfinexExchangeAdapter.class);

Expand Down Expand Up @@ -128,17 +128,6 @@ public final class BitfinexExchangeAdapter extends AbstractExchangeAdapter imple
*/
private static final String UNEXPECTED_IO_ERROR_MSG = "Failed to connect to Exchange due to unexpected IO error.";

/**
* Used for building error messages for missing config.
*/
private static final String CONFIG_IS_NULL_OR_ZERO_LENGTH = " cannot be null or zero length! HINT: is the value set in the ";

/**
* Your Bitfinex API keys and connection timeout config.
* This file must be on BX-bot's runtime classpath located at: ./resources/bitfinex/bitfinex-config.properties
*/
private static final String CONFIG_FILE = "bitfinex/bitfinex-config.properties";

/**
* Name of PUBLIC key prop in config file.
*/
Expand All @@ -149,21 +138,11 @@ public final class BitfinexExchangeAdapter extends AbstractExchangeAdapter imple
*/
private static final String SECRET_PROPERTY_NAME = "secret";

/**
* Name of connection timeout property in config file.
*/
private static final String CONNECTION_TIMEOUT_PROPERTY_NAME = "connection-timeout";

/**
* Nonce used for sending authenticated messages to the exchange.
*/
private static long nonce = 0;

/**
* The connection timeout in SECONDS for terminating hung connections to the exchange.
*/
private int connectionTimeout;

/**
* Used to indicate if we have initialised the MAC authentication protocol.
*/
Expand Down Expand Up @@ -191,15 +170,14 @@ public final class BitfinexExchangeAdapter extends AbstractExchangeAdapter imple
private Gson gson;


/**
* Constructor initialises the Exchange Adapter for using the Bitfinex API.
*/
public BitfinexExchangeAdapter() {
@Override
public void init(ExchangeConfig config) {

// set the initial nonce used in the secure messaging.
nonce = System.currentTimeMillis() / 1000;
LogUtils.log(LOG, Level.INFO, () -> "About to initialise Bitfinex ExchangeConfig: " + config);
setAuthenticationConfig(config);
setNetworkConfig(config);

loadConfig();
nonce = System.currentTimeMillis() / 1000; // set the initial nonce used in the secure messaging.
initSecureMessageLayer();
initGson();
}
Expand Down Expand Up @@ -1023,82 +1001,11 @@ private void initSecureMessageLayer() {
// Config methods
// ------------------------------------------------------------------------------------------------

/**
* Loads Exchange Adapter config.
*/
private void loadConfig() {

final String configFile = getConfigFileLocation();
final Properties configEntries = new Properties();
final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(configFile);

if (inputStream == null) {
final String errorMsg = "Cannot find Bitfinex config at: " + configFile + " HINT: is it on BX-bot's classpath?";
LOG.error(errorMsg);
throw new IllegalStateException(errorMsg);
}

try {
configEntries.load(inputStream);

/*
* Grab the public key
*/
key = configEntries.getProperty(KEY_PROPERTY_NAME);

// WARNING: careful when you log this
// if (LOG.isInfoEnabled()) {
// LOG.info(KEY_PROPERTY_NAME + ": " + key);
// }
private void setAuthenticationConfig(ExchangeConfig exchangeConfig) {

if (key == null || key.length() == 0) {
final String errorMsg = KEY_PROPERTY_NAME + CONFIG_IS_NULL_OR_ZERO_LENGTH + configFile + "?";
LOG.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
}

/*
* Grab the private key
*/
secret = configEntries.getProperty(SECRET_PROPERTY_NAME);

// WARNING: careful when you log this
// if (LOG.isInfoEnabled()) {
// LOG.info(SECRET_PROPERTY_NAME + ": " + secret);
// }

if (secret == null || secret.length() == 0) {
final String errorMsg = SECRET_PROPERTY_NAME + CONFIG_IS_NULL_OR_ZERO_LENGTH + configFile + "?";
LOG.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
}

/*
* Grab the connection timeout
*/
connectionTimeout = Integer.parseInt( // will barf if not a number; we want this to fail fast.
configEntries.getProperty(CONNECTION_TIMEOUT_PROPERTY_NAME));
if (connectionTimeout == 0) {
final String errorMsg = CONNECTION_TIMEOUT_PROPERTY_NAME + " cannot be 0 value!"
+ " HINT: is the value set in the " + configFile + "?";
LOG.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
}

LogUtils.log(LOG, Level.INFO, () -> CONNECTION_TIMEOUT_PROPERTY_NAME + ": " + connectionTimeout);

} catch (IOException e) {
final String errorMsg = "Failed to load Exchange config: " + configFile;
LOG.error(errorMsg, e);
throw new IllegalStateException(errorMsg, e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
final String errorMsg = "Failed to close input stream for: " + configFile;
LOG.error(errorMsg, e);
}
}
final AuthenticationConfig authenticationConfig = getAuthenticationConfig(exchangeConfig);
key = getAuthenticationConfigItem(authenticationConfig, KEY_PROPERTY_NAME);
secret = getAuthenticationConfigItem(authenticationConfig, SECRET_PROPERTY_NAME);
}

// ------------------------------------------------------------------------------------------------
Expand All @@ -1113,13 +1020,6 @@ private void initGson() {
gson = gsonBuilder.create();
}

/*
* Hack for unit-testing config loading.
*/
private static String getConfigFileLocation() {
return CONFIG_FILE;
}

/*
* Hack for unit-testing map params passed to transport layer.
*/
Expand Down
Loading

0 comments on commit aba511a

Please sign in to comment.