package org.knowm.xchange.btcchina.service.rest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.btcchina.BTCChinaAdapters;
import org.knowm.xchange.btcchina.BTCChinaExchangeException;
import org.knowm.xchange.btcchina.dto.trade.request.BTCChinaGetOrdersRequest;
import org.knowm.xchange.btcchina.dto.trade.request.BTCChinaTransactionsRequest;
import org.knowm.xchange.btcchina.dto.trade.response.BTCChinaBooleanResponse;
import org.knowm.xchange.btcchina.dto.trade.response.BTCChinaGetOrdersResponse;
import org.knowm.xchange.btcchina.dto.trade.response.BTCChinaIntegerResponse;
import org.knowm.xchange.btcchina.dto.trade.response.BTCChinaTransactionsResponse;
import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.Order.OrderType;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.dto.trade.OpenOrders;
import org.knowm.xchange.dto.trade.UserTrades;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.exceptions.NotAvailableFromExchangeException;
import org.knowm.xchange.exceptions.NotYetImplementedForExchangeException;
import org.knowm.xchange.service.trade.TradeService;
import org.knowm.xchange.service.trade.params.*;
import org.knowm.xchange.service.trade.params.orders.OpenOrdersParams;
import org.knowm.xchange.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Implementation of the trade service for BTCChina.
* <ul>
* <li>Provides access to trade functions</li>
* </ul>
*
* @author ObsessiveOrange
*/
public class BTCChinaTradeService extends BTCChinaTradeServiceRaw implements TradeService {
private final Logger log = LoggerFactory.getLogger(BTCChinaTradeService.class);
/**
* Constructor
*
* @param exchange
*/
public BTCChinaTradeService(Exchange exchange) {
super(exchange);
}
@Override
public OpenOrders getOpenOrders() throws IOException {
return getOpenOrders(createOpenOrdersParams());
}
@Override
public OpenOrders getOpenOrders(OpenOrdersParams params) throws ExchangeException, NotAvailableFromExchangeException, NotYetImplementedForExchangeException, IOException {
final List<LimitOrder> limitOrders = new ArrayList<LimitOrder>();
List<LimitOrder> page;
do {
BTCChinaGetOrdersResponse response = getBTCChinaOrders(true, BTCChinaGetOrdersRequest.ALL_MARKET, null, limitOrders.size());
page = new ArrayList<LimitOrder>();
page.addAll(BTCChinaAdapters.adaptOrders(response.getResult(), null));
limitOrders.addAll(page);
} while (page.size() >= BTCChinaGetOrdersRequest.DEFAULT_LIMIT);
return new OpenOrders(limitOrders);
}
@Override
public String placeMarketOrder(MarketOrder marketOrder) throws IOException {
final BigDecimal amount = marketOrder.getTradableAmount();
final String market = BTCChinaAdapters.adaptMarket(marketOrder.getCurrencyPair()).toUpperCase();
final BTCChinaIntegerResponse response;
if (marketOrder.getType() == OrderType.BID) {
response = buy(null, amount, market);
} else {
response = sell(null, amount, market);
}
return response.getResult().toString();
}
@Override
public String placeLimitOrder(LimitOrder limitOrder) throws IOException {
final BigDecimal price = limitOrder.getLimitPrice();
final BigDecimal amount = limitOrder.getTradableAmount();
final String market = BTCChinaAdapters.adaptMarket(limitOrder.getCurrencyPair()).toUpperCase();
final BTCChinaIntegerResponse response;
if (limitOrder.getType() == OrderType.BID) {
response = buy(price, amount, market);
} else {
response = sell(price, amount, market);
}
return response.getResult().toString();
}
@Override
public boolean cancelOrder(String orderId) throws IOException {
boolean ret;
try {
BTCChinaBooleanResponse response = cancelBTCChinaOrder(Integer.parseInt(orderId));
ret = response.getResult();
} catch (BTCChinaExchangeException e) {
if (e.getErrorCode() == -32026) {
// Order already completed
ret = false;
} else {
throw e;
}
}
return ret;
}
private UserTrades getUserTrades(String type, Integer limit, Integer offset, Integer since, String sincetype) throws IOException {
log.debug("type: {}, limit: {}, offset: {}, since: {}, sincetype: {}", type, limit, offset, since, sincetype);
final BTCChinaTransactionsResponse response = getTransactions(type, limit, offset, since, sincetype);
return BTCChinaAdapters.adaptTransactions(response.getResult().getTransactions());
}
/**
* Supported parameters: {@link TradeHistoryParamPaging} {@link TradeHistoryParamsTimeSpan#getStartTime()}
* {@link TradeHistoryParamsIdSpan#getStartId()} used only if startTime is not set
*/
@Override
public UserTrades getTradeHistory(TradeHistoryParams params) throws ExchangeException, IOException {
String type = BTCChinaTransactionsRequest.TYPE_ALL;
if (params instanceof BTCChinaTradeHistoryParams) {
type = ((BTCChinaTradeHistoryParams) params).type;
}
Integer limit = null;
Integer offset = null;
if (params instanceof TradeHistoryParamPaging) {
Integer pageNumber = ((TradeHistoryParamPaging) params).getPageNumber();
limit = ((TradeHistoryParamPaging) params).getPageLength();
offset = (limit == null || pageNumber == null) ? null : limit * pageNumber;
}
String sincetype = null;
Integer since = null;
if (params instanceof TradeHistoryParamsIdSpan) {
String startId = ((TradeHistoryParamsIdSpan) params).getStartId();
if (startId != null) {
since = Integer.valueOf(startId);
sincetype = BTCChinaTransactionsRequest.SINCE_ID;
}
}
if (params instanceof TradeHistoryParamsTimeSpan) {
Date startTime = ((TradeHistoryParamsTimeSpan) params).getStartTime();
if (startTime != null) {
since = (int) DateUtils.toUnixTime(startTime);
sincetype = BTCChinaTransactionsRequest.SINCE_TIME;
}
}
return getUserTrades(type, limit, offset, since, sincetype);
}
@Override
public TradeHistoryParams createTradeHistoryParams() {
return new BTCChinaTradeHistoryParams();
}
@Override
public OpenOrdersParams createOpenOrdersParams() {
return null;
}
public static class BTCChinaTradeHistoryParams extends DefaultTradeHistoryParamPaging
implements TradeHistoryParamsTimeSpan, TradeHistoryParamsIdSpan {
private String type = BTCChinaTransactionsRequest.TYPE_ALL;
private Date startTime;
private String startId;
public BTCChinaTradeHistoryParams() {
}
public BTCChinaTradeHistoryParams(Integer pageLength, Integer pageNumber, String type, Date startTime, Integer startId) {
super(pageLength, pageNumber);
this.type = type;
this.startTime = startTime;
if (startId != null) {
setStartId(startId.toString());
}
}
@Override
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
@Override
public Date getStartTime() {
return startTime;
}
@Override
public void setEndTime(Date endTime) {
}
@Override
public Date getEndTime() {
return null;
}
@Override
public void setStartId(String startId) {
this.startId = startId;
}
@Override
public String getStartId() {
return startId;
}
@Override
public void setEndId(String endId) {
}
@Override
public String getEndId() {
return null;
}
}
@Override
public Collection<Order> getOrder(String... orderIds)
throws ExchangeException, NotAvailableFromExchangeException, NotYetImplementedForExchangeException, IOException {
throw new NotYetImplementedForExchangeException();
}
}