Skip to content

Commit

Permalink
Merge pull request #4901 from bigscoop/coinex
Browse files Browse the repository at this point in the history
[coinex] Add market orders
  • Loading branch information
timmolter authored Jun 11, 2024
2 parents 4e94695 + 6500c0f commit 8042003
Show file tree
Hide file tree
Showing 17 changed files with 452 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.knowm.xchange.coinex;

import java.math.MathContext;
import java.time.Instant;
import java.util.Collection;
import java.util.Date;
Expand All @@ -9,10 +10,13 @@
import java.util.stream.Collectors;
import lombok.experimental.UtilityClass;
import org.knowm.xchange.coinex.dto.account.CoinexBalanceInfo;
import org.knowm.xchange.coinex.dto.account.CoinexMarketType;
import org.knowm.xchange.coinex.dto.account.CoinexOrder;
import org.knowm.xchange.coinex.dto.marketdata.CoinexCurrencyPairInfo;
import org.knowm.xchange.coinex.dto.marketdata.CoinexMarketDepth;
import org.knowm.xchange.coinex.dto.marketdata.CoinexTickerV1;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.Order.OrderType;
import org.knowm.xchange.dto.account.Balance;
import org.knowm.xchange.dto.account.Wallet;
Expand All @@ -21,6 +25,7 @@
import org.knowm.xchange.dto.marketdata.Ticker.Builder;
import org.knowm.xchange.dto.meta.InstrumentMetaData;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.instrument.Instrument;

@UtilityClass
Expand Down Expand Up @@ -52,6 +57,18 @@ public Balance toBalance(CoinexBalanceInfo balance) {
}


public CoinexOrder toCoinexOrder(MarketOrder marketOrder) {
return CoinexOrder.builder()
.currencyPair((CurrencyPair) marketOrder.getInstrument())
.marketType(CoinexMarketType.SPOT)
.side(marketOrder.getType())
.type("market")
.clientId(marketOrder.getUserReference())
.amount(marketOrder.getOriginalAmount())
.build();
}


public CurrencyPair toCurrencyPair(String symbol) {
return SYMBOL_TO_CURRENCY_PAIR.get(symbol);
}
Expand All @@ -67,6 +84,50 @@ public InstrumentMetaData toInstrumentMetaData(CoinexCurrencyPairInfo coinexCurr
}


public Order toOrder(CoinexOrder coinexOrder) {
Order.Builder builder;
Instrument instrument = coinexOrder.getCurrencyPair();
OrderType orderType = coinexOrder.getSide();

switch (coinexOrder.getType()) {
case "market":
builder = new MarketOrder.Builder(orderType, instrument);
break;
case "limit":
builder = new LimitOrder.Builder(orderType, instrument)
.limitPrice(coinexOrder.getPrice());
break;
default:
throw new IllegalArgumentException("Can't map " + coinexOrder.getType());
}

if (orderType == OrderType.BID) {
// buy orders fill quote
builder.cumulativeAmount(coinexOrder.getFilledQuoteAmount());
}
else if (orderType == OrderType.ASK) {
// sell orders fill asset
builder.cumulativeAmount(coinexOrder.getFilledAssetAmount());
}
else {
throw new IllegalArgumentException("Can't map " + orderType);
}

// average price
if (coinexOrder.getFilledAssetAmount() != null && coinexOrder.getFilledQuoteAmount() != null && coinexOrder.getFilledAssetAmount().signum() > 0) {
builder.averagePrice(coinexOrder.getFilledQuoteAmount().divide(coinexOrder.getFilledAssetAmount(), MathContext.DECIMAL32));
}

return builder
.id(String.valueOf(coinexOrder.getOrderId()))
.originalAmount(coinexOrder.getAmount())
.userReference(coinexOrder.getClientId())
.timestamp(Date.from(coinexOrder.getCreatedAt()))
.orderStatus(coinexOrder.getStatus())
.build();
}


public OrderBook toOrderBook(CoinexMarketDepth coinexMarketDepth) {
List<LimitOrder> asks = coinexMarketDepth.getDepth().getAsks().stream()
.map(priceSizeEntry ->
Expand Down Expand Up @@ -114,7 +175,7 @@ public Ticker toTicker(Instrument instrument, CoinexTickerV1 coinexTickerV1, Ins

builder
.open(coinexTickerV1.getOpen24h())
.last(coinexTickerV1.getVolume24h())
.last(coinexTickerV1.getLast())
.bid(coinexTickerV1.getBestBidPrice())
.ask(coinexTickerV1.getBestAskPrice())
.high(coinexTickerV1.getHigh24h())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package org.knowm.xchange.coinex;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.List;
import org.knowm.xchange.coinex.dto.CoinexException;
import org.knowm.xchange.coinex.dto.CoinexResponse;
import org.knowm.xchange.coinex.dto.account.CoinexBalanceInfo;
import org.knowm.xchange.coinex.dto.account.CoinexOrder;
import si.mazi.rescu.ParamsDigest;
import si.mazi.rescu.SynchronizedValueFactory;

Expand All @@ -25,5 +29,25 @@ CoinexResponse<List<CoinexBalanceInfo>> balances(
@HeaderParam("X-COINEX-SIGN") ParamsDigest signer)
throws IOException, CoinexException;

@POST
@Path("v2/spot/order")
@Consumes(MediaType.APPLICATION_JSON)
CoinexResponse<CoinexOrder> createOrder(
@HeaderParam("X-COINEX-KEY") String apiKey,
@HeaderParam("X-COINEX-TIMESTAMP") SynchronizedValueFactory<Long> timestamp,
@HeaderParam("X-COINEX-SIGN") ParamsDigest signer,
CoinexOrder coinexOrder)
throws IOException, CoinexException;

@GET
@Path("v2/spot/order-status")
CoinexResponse<CoinexOrder> orderStatus(
@HeaderParam("X-COINEX-KEY") String apiKey,
@HeaderParam("X-COINEX-TIMESTAMP") SynchronizedValueFactory<Long> timestamp,
@HeaderParam("X-COINEX-SIGN") ParamsDigest signer,
@QueryParam("market") String market,
@QueryParam("order_id") String orderId)
throws IOException, CoinexException;


}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
import org.knowm.xchange.coinex.dto.CoinexException;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.exceptions.InstrumentNotValidException;
import org.knowm.xchange.exceptions.OrderNotValidException;

@UtilityClass
public class CoinexErrorAdapter {

public final int ORDER_NOT_FOUND = 3600;
public final int INVALID_MARKET_CODE = 3639;

public ExchangeException adapt(CoinexException e) {

switch (e.getCode()) {
case ORDER_NOT_FOUND:
return new OrderNotValidException(e.getMessage(), e);

case INVALID_MARKET_CODE:
return new InstrumentNotValidException(e.getMessage(), e);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.knowm.xchange.coinex.service.CoinexAccountService;
import org.knowm.xchange.coinex.service.CoinexMarketDataService;
import org.knowm.xchange.coinex.service.CoinexMarketDataServiceRaw;
import org.knowm.xchange.coinex.service.CoinexTradeService;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.meta.ExchangeMetaData;
import org.knowm.xchange.dto.meta.InstrumentMetaData;
Expand All @@ -21,6 +22,7 @@ public class CoinexExchange extends BaseExchange {
protected void initServices() {
accountService = new CoinexAccountService(this);
marketDataService = new CoinexMarketDataService(this);
tradeService = new CoinexTradeService(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.knowm.xchange.coinex.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
Expand All @@ -14,6 +15,9 @@ public void configureObjectMapper(ObjectMapper objectMapper) {
// by default read timetamps as milliseconds
objectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);

// don't write nulls
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

// enable parsing to Instant
objectMapper.registerModule(new JavaTimeModule());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.knowm.xchange.coinex.config.converter;

import com.fasterxml.jackson.databind.util.StdConverter;
import org.knowm.xchange.coinex.CoinexAdapters;
import org.knowm.xchange.currency.CurrencyPair;

/**
* Converts {@code CurrencyPair} to string
*/
public class CurrencyPairToStringConverter extends StdConverter<CurrencyPair, String> {

@Override
public String convert(CurrencyPair value) {
return CoinexAdapters.toString(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.knowm.xchange.coinex.config.converter;

import com.fasterxml.jackson.databind.util.StdConverter;
import org.knowm.xchange.dto.Order.OrderType;

/**
* Converts {@code OrderType} to string
*/
public class OrderTypeToStringConverter extends StdConverter<OrderType, String> {

@Override
public String convert(OrderType value) {
switch (value) {
case BID:
return "buy";
case ASK:
return "sell";
default:
throw new IllegalArgumentException("Can't map " + value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.knowm.xchange.coinex.config.converter;

import com.fasterxml.jackson.databind.util.StdConverter;
import org.knowm.xchange.dto.Order.OrderStatus;

/**
* Converts string to {@code OrderStatus}
*/
public class StringToOrderStatusConverter extends StdConverter<String, OrderStatus> {

@Override
public OrderStatus convert(String value) {
switch (value) {
case "open":
return OrderStatus.OPEN;
case "part_filled":
return OrderStatus.PARTIALLY_FILLED;
case "filled":
return OrderStatus.FILLED;
case "part_canceled":
return OrderStatus.PARTIALLY_CANCELED;
case "canceled":
return OrderStatus.CANCELED;
default:
throw new IllegalArgumentException("Can't map " + value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.knowm.xchange.coinex.config.converter;

import com.fasterxml.jackson.databind.util.StdConverter;
import org.knowm.xchange.dto.Order.OrderType;

/**
* Converts string to {@code OrderType}
*/
public class StringToOrderTypeConverter extends StdConverter<String, OrderType> {

@Override
public OrderType convert(String value) {
switch (value) {
case "buy":
return OrderType.BID;
case "sell":
return OrderType.ASK;
default:
throw new IllegalArgumentException("Can't map " + value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.knowm.xchange.coinex.dto.account;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum CoinexMarketType {

SPOT,
MARGIN,
FUTURES;

}
Loading

0 comments on commit 8042003

Please sign in to comment.