Bitfinex implementation upgraded to AdvancedExchange asynchronous implementation

This commit is contained in:
b00lean 2015-01-19 10:47:48 +01:00
parent e904fd1c81
commit 8c968e1e09
1 changed files with 137 additions and 16 deletions

View File

@ -22,18 +22,15 @@ package com.generalbytes.batm.server.extensions.extra.bitcoin.exchanges.bitfinex
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import com.generalbytes.batm.server.extensions.IRateSource;
import com.generalbytes.batm.server.extensions.*;
import com.xeiam.xchange.ExchangeException;
import com.xeiam.xchange.dto.trade.LimitOrder;
import com.xeiam.xchange.dto.trade.OpenOrders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.generalbytes.batm.server.extensions.ICurrencies;
import com.generalbytes.batm.server.extensions.IExchange;
import com.xeiam.xchange.Exchange;
import com.xeiam.xchange.ExchangeFactory;
import com.xeiam.xchange.ExchangeSpecification;
@ -45,7 +42,7 @@ import com.xeiam.xchange.service.polling.PollingAccountService;
import com.xeiam.xchange.service.polling.PollingMarketDataService;
import com.xeiam.xchange.service.polling.PollingTradeService;
public class BitfinexExchange implements IExchange, IRateSource {
public class BitfinexExchange implements IExchangeAdvanced, IRateSource {
private static final Logger log = LoggerFactory.getLogger("batm.master.BitfinexExchange");
private Exchange exchange = null;
@ -223,8 +220,9 @@ public class BitfinexExchange implements IExchange, IRateSource {
OpenOrders openOrders = tradeService.getOpenOrders();
for (LimitOrder openOrder : openOrders.getOpenOrders()) {
log.debug("openOrder = " + openOrder);
if (orderId.equalsIgnoreCase(openOrder.getId())) {
if (orderId.equals(openOrder.getId())) {
orderFound = true;
break;
}
}
if (orderFound) {
@ -249,6 +247,19 @@ public class BitfinexExchange implements IExchange, IRateSource {
return null;
}
@Override
public ITask createPurchaseCoinsTask(BigDecimal amount, String cryptoCurrency, String fiatCurrencyToUse, String description) {
if (!ICurrencies.BTC.equalsIgnoreCase(cryptoCurrency)) {
log.error("Bitfinex implementation supports only " + ICurrencies.BTC);
return null;
}
if (!ICurrencies.USD.equalsIgnoreCase(fiatCurrencyToUse)) {
log.error("Bitfinex supports only " + ICurrencies.USD );
return null;
}
return new PurchaseCoinsTaks(amount,cryptoCurrency,fiatCurrencyToUse,description);
}
@Override
public String getDepositAddress(String cryptoCurrency) {
if (!ICurrencies.BTC.equalsIgnoreCase(cryptoCurrency)) {
@ -264,17 +275,127 @@ public class BitfinexExchange implements IExchange, IRateSource {
return null;
}
public static void main(String[] args) {
BitfinexExchange ex = new BitfinexExchange("UKe2l4ij2jKg8zwaCIJ9qpwIasJ4EhfxiiB0KToG9Ky","35XkZ6IJD9EOfRex80xHwXSgaun7uXdBgzVdiOg5XOi");
BigDecimal btc = ex.getCryptoBalance(ICurrencies.BTC);
System.out.println("btc = " + btc);
BigDecimal fiatBalance = ex.getFiatBalance(ICurrencies.USD);
System.out.println("fiatBalance = " + fiatBalance);
class PurchaseCoinsTaks implements ITask {
private long MAXIMUM_TIME_TO_WAIT_FOR_ORDER_TO_FINISH = 5 * 60 * 60 * 1000; //5 hours
String test = ex.sendCoins("15nvjrMZbxyLAAr9RAnqkoMXcFriAmbeLE", new BigDecimal("0.02"), ICurrencies.BTC, "Test");
System.out.println("test = " + test);
private BigDecimal amount;
private String cryptoCurrency;
private String fiatCurrencyToUse;
private String description;
private String orderId;
private String result;
private boolean finished;
PurchaseCoinsTaks(BigDecimal amount, String cryptoCurrency, String fiatCurrencyToUse, String description) {
this.amount = amount;
this.cryptoCurrency = cryptoCurrency;
this.fiatCurrencyToUse = fiatCurrencyToUse;
this.description = description;
}
@Override
public boolean onCreate() {
log.info("Calling Bitfinex exchange (purchase " + amount + " " + cryptoCurrency + ")");
PollingAccountService accountService = getExchange().getPollingAccountService();
PollingTradeService tradeService = getExchange().getPollingTradeService();
try {
log.debug("AccountInfo as String: " + accountService.getAccountInfo().toString());
CurrencyPair currencyPair = new CurrencyPair(cryptoCurrency, fiatCurrencyToUse);
MarketOrder order = new MarketOrder(OrderType.BID, amount, currencyPair);
log.debug("marketOrder = " + order);
orderId = tradeService.placeMarketOrder(order);
log.debug("orderId = " + orderId + " " + order);
try {
Thread.sleep(2000); //give exchange 2 seconds to reflect open order in order book
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
log.error("Bitfinex exchange (purchaseCoins) failed with message: " + e.getMessage());
} catch (Throwable e) {
e.printStackTrace();
}
return (orderId != null);
}
@Override
public boolean onDoStep() {
if (orderId == null) {
log.debug("Giving up on waiting for trade to complete. Because it did not happen");
finished = true;
result = "Skipped";
return false;
}
PollingTradeService tradeService = getExchange().getPollingTradeService();
// get open orders
boolean orderProcessed = false;
long checkTillTime = System.currentTimeMillis() + MAXIMUM_TIME_TO_WAIT_FOR_ORDER_TO_FINISH;
if (System.currentTimeMillis() > checkTillTime) {
log.debug("Giving up on waiting for trade " + orderId + " to complete");
finished = true;
return false;
}
log.debug("Open orders:");
boolean orderFound = false;
try {
OpenOrders openOrders = tradeService.getOpenOrders();
for (LimitOrder openOrder : openOrders.getOpenOrders()) {
log.debug("openOrder = " + openOrder);
if (orderId.equals(openOrder.getId())) {
orderFound = true;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
if (orderFound) {
log.debug("Waiting for order to be processed.");
}else{
orderProcessed = true;
}
if (orderProcessed) {
result = orderId;
finished = true;
}
return result != null;
}
@Override
public boolean isFinished() {
return finished;
}
@Override
public String getResult() {
return result;
}
@Override
public boolean isFailed() {
return finished && result == null;
}
@Override
public void onFinish() {
log.debug("Purchase task finished.");
}
@Override
public long getShortestTimeForNexStepInvocation() {
return 5 * 1000; //it doesn't make sense to run step sooner than after 5 seconds
}
}
}