XChange开发常见问题

1. XChange 的发布周期是多少?

XChange 是一个独特的项目,因为交易所(现在超过 60 个)处于不断变化的状态。API endpoints 可以更改,返回的 JSON 可以更改,整个 API 版本可以被重写,货币对可以被添加/删除等。在 XChange 发布后不久,发生一些重要的 API 更改,都是毫无疑问有可能发生的。修复程序将通过对develop分支的拉取请求来实现,将修复集成到项目中的唯一方法是使项目依赖于最新的 SNAPSHOT jar。XChange 按基于"请求"的计划发布,但每月释放的速度不超过一次。

2. 我收到"Invalid nonce"错误

通常,当使用相同的 API 密钥运行客户端 API 的不同实现时。不同的实现可能使用不同的 Nonce 生成策略。一个客户端可以生成更高的 nonce,之后另一个客户端可以生成较低的值,但它必须始终高于给定 API 密钥的任何以前的 nonce。要解决此问题,可以生成一个新的 API 密钥。如果要交替使用不同的实现,请保留两个密钥,并让每个应用使用其自己的密钥。有关 nonce 生成的详细信息,请参阅:https://github.com/timmolter/XChange/wiki/Design-Notes中文

3. 在哪里配置了 http 读取超时?

请参阅https://github.com/mmazi/rescu。“可以通过在类路径中添加rescu.properties文件来配置 Rescu。对于 Maven 项目,只需把rescu.properties放入资源目录中,rescu 将自动拾取配置。

4. 如何将API Key 和Secret Key添加到ExchangeSpecification

通常,对于公共市场数据访问,您不需要添加任何 API 密钥,创建一个ExchangeSpecification 用于访问MarketDataService,如下实现:

// Use the factory to get Bitstamp exchange API using default settings
Exchange bitstamp = ExchangeFactory.INSTANCE.createExchange(BitstampExchange.class.getName());

// Interested in the public market data feed (no authentication)
MarketDataService marketDataService = bitstamp.getMarketDataService();

对于访问TradeServiceAccountService ,需要使用secret API keys创建Exchange ,有几种方法可以实现此目的。请注意,不同的exchanges可能需要不同的secret keys和(或)其他字段。请确保签出xchange-examples模块以找出特定的示例代码。

4.1 硬编码密钥

ExchangeSpecification exSpec = new BitstampExchange().getDefaultExchangeSpecification();
exSpec.setUserName("34387");
exSpec.setApiKey("a4SDmpl9s6xWJS5fkKRT6yn41vXuY0AM");
exSpec.setSecretKey("sisJixU6Xd0d1yr6w02EHCb9UwYzTNuj");
Exchange exchange = ExchangeFactory.INSTANCE.createExchange(exSpec);

4.2 类路径上的 JSON 文件

/**
 * Create a exchange using the keys provided in a bitcoinde/exchangeConfiguration.json file on the classpath.
 *
 * @return Create exchange or null if .json file was not on classpath.
 */
public static Exchange createExchangeFromJsonConfiguration() throws IOException {

  ExchangeSpecification exSpec = new ExchangeSpecification(BitcoindeExchange.class);
  ObjectMapper mapper = new ObjectMapper();
  InputStream is = ExchangeUtils.class.getClassLoader().getResourceAsStream("bitcoinde/exchangeConfiguration.json");
  if (is == null) {
    logger.warn("No bitcoinde/exchangeConfiguration.json file found. Returning null exchange.");
    return null;
  }
  try {
    ExchangeConfiguration conf = mapper.readValue(is, ExchangeConfiguration.class);
    logger.debug(conf.toString());

    if (conf.apiKey != null)
      exSpec.setApiKey(conf.apiKey);
    if (conf.secretKey != null)
      exSpec.setSecretKey(conf.secretKey);
  } catch (Exception e) {
    logger.warn("An exception occured while loading the bitcoinde/exchangeConfiguration.json file from the classpath. " + "Returning null exchange.", e);
    return null;
  }

  Exchange exchange = ExchangeFactory.INSTANCE.createExchange(exSpec);
  exchange.remoteInit();
  return exchange;
}

}

4.3 程序参数

public static void main(String[] args) throws IOException {

    // API key with All Permissions.
    String publicKey = args[0];
    String privateKey = args[1];

    ExchangeSpecification spec = new ExchangeSpecification(BTCTradeExchange.class);
    spec.setApiKey(publicKey);
    spec.setSecretKey(privateKey);

    Exchange exchange = ExchangeFactory.INSTANCE.createExchange(spec);
}