Skip to content

Commit 16f1a2f

Browse files
committed
Implementation of CoinEgg Exchange
- Fully implemented MarketData Service - Patrial implemention of AccountData Service - DTO Objects and Deserializaition of Trade Service Objects
1 parent 141103d commit 16f1a2f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1741
-1
lines changed

pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
<module>xchange-ccex</module>
114114
<module>xchange-cexio</module>
115115
<module>xchange-coinbase</module>
116+
<module>xchange-coinegg</module>
116117
<module>xchange-coinmarketcap</module>
117118
<module>xchange-coinfloor</module>
118119
<module>xchange-coinmate</module>
@@ -153,6 +154,7 @@
153154
<module>xchange-vircurex</module>
154155
<module>xchange-yobit</module>
155156
<module>xchange-wex</module>
157+
<module>xchange-coinegg</module>
156158
</modules>
157159

158160
<repositories>

xchange-bitz/src/main/java/org/xchange/bitz/dto/marketdata/BitZTicker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
public class BitZTicker {
88

9-
private final BigDecimal last;
9+
private final BigDecimal last;
1010
private final BigDecimal high;
1111
private final BigDecimal low;
1212
private final BigDecimal volume;

xchange-coinegg/api-specification.txt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
CoinEgg Exchange API Specification
2+
================================
3+
4+
Last Revision : 13/01/2018
5+
API Version : 1.0
6+
7+
Authentication Type: API Key
8+
Response Type: JSON Object
9+
10+
11+
Overview
12+
------------
13+
14+
Supports Market Data Service : True
15+
Supports Account Service : False (Docs Only)
16+
Supports Trade Service : False (Docs Only)
17+
18+
19+
Implementation Considerations
20+
-----------------------------
21+
Despite documentation for Trade and Accounts services, the exchange
22+
has no working service running. Hence can be implemented yet will not
23+
be functional.
24+
25+
The API has been implemented, in preparation in case the exchange runs the service
26+
yet is unaccessible from the Exchange class.
27+
28+
Documentation
29+
-------------
30+
https://www.coinegg.com/explain.api.html
31+
32+
33+
Method Endpoint Description
34+
-------------------------------------------------------------
35+
GET /api/v1/ticker/ Get the price data
36+
GET /api/v1/depth/ Get depth data
37+
GET /api/v1/orders/ Get the deal
38+
39+
POST /api/v1/balance/
40+
POST /api/v1/trade_list/
41+
POST /api/v1/trade_view/
42+
POST /api/v1/trade_cancel/
43+
POST /api/v1/trade_add/
44+
45+
46+
REQUEST LIMITS
47+
--------------
48+
No defined request limits.

xchange-coinegg/future-features.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Bit-Z Exchange Future Features
2+
================================
3+
4+
Last Revision : 04/01/2018
5+
6+
- When Avaiable By Exchange
7+
- Implement Full Trading Service
8+
- Implement Full Account Service

xchange-coinegg/pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>org.knowm.xchange</groupId>
7+
<artifactId>xchange-parent</artifactId>
8+
<version>4.3.3-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>xchange-coinegg</artifactId>
12+
13+
<name>XChange CoinEgg</name>
14+
<description>XChange implementation for the CoinEgg Exchange</description>
15+
16+
<url>http://knowm.org/open-source/xchange/</url>
17+
<inceptionYear>2012</inceptionYear>
18+
19+
<organization>
20+
<name>Knowm Inc.</name>
21+
<url>http://knowm.org/open-source/xchange/</url>
22+
</organization>
23+
24+
<!-- Parent provides default configuration for dependencies -->
25+
<dependencies>
26+
27+
<dependency>
28+
<groupId>org.knowm.xchange</groupId>
29+
<artifactId>xchange-core</artifactId>
30+
<version>4.3.3-SNAPSHOT</version>
31+
<exclusions>
32+
<!-- because the pusher jar has its own fork of Java-Websocket -->
33+
<exclusion>
34+
<groupId>org.java-websocket</groupId>
35+
<artifactId>Java-WebSocket</artifactId>
36+
</exclusion>
37+
</exclusions>
38+
</dependency>
39+
40+
</dependencies>
41+
42+
</project>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.xchange.coinegg;
2+
3+
import java.io.IOException;
4+
5+
import javax.ws.rs.GET;
6+
import javax.ws.rs.Path;
7+
import javax.ws.rs.PathParam;
8+
import javax.ws.rs.Produces;
9+
import javax.ws.rs.core.MediaType;
10+
11+
import org.xchange.coinegg.dto.marketdata.CoinEggOrder;
12+
import org.xchange.coinegg.dto.marketdata.CoinEggTicker;
13+
import org.xchange.coinegg.dto.marketdata.CoinEggTrades;
14+
15+
@Path("api/v1")
16+
@Produces(MediaType.APPLICATION_JSON)
17+
public interface CoinEgg {
18+
19+
@GET
20+
@Path("ticker?coin={symbol}")
21+
CoinEggTicker getTicker(@PathParam("symbol") String symbol) throws IOException;
22+
23+
@GET
24+
@Path("depth?coin={symbol}")
25+
CoinEggTrades getTrades(@PathParam("symbol") String symbol) throws IOException;
26+
27+
@GET
28+
@Path("orders?coin={symbol}")
29+
CoinEggOrder[] getOrders(@PathParam("symbol") String symbol) throws IOException;
30+
31+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.xchange.coinegg;
2+
3+
import java.math.BigDecimal;
4+
import java.util.ArrayList;
5+
import java.util.Date;
6+
import java.util.List;
7+
import java.util.stream.Collectors;
8+
import java.util.stream.Stream;
9+
10+
import org.knowm.xchange.currency.CurrencyPair;
11+
import org.knowm.xchange.dto.Order.OrderType;
12+
import org.knowm.xchange.dto.marketdata.OrderBook;
13+
import org.knowm.xchange.dto.marketdata.Ticker;
14+
import org.knowm.xchange.dto.marketdata.Trade;
15+
import org.knowm.xchange.dto.marketdata.Trades;
16+
import org.knowm.xchange.dto.trade.LimitOrder;
17+
import org.knowm.xchange.utils.DateUtils;
18+
import org.xchange.coinegg.dto.marketdata.CoinEggOrder;
19+
import org.xchange.coinegg.dto.marketdata.CoinEggTicker;
20+
import org.xchange.coinegg.dto.marketdata.CoinEggTrades;
21+
import org.xchange.coinegg.dto.marketdata.CoinEggOrder.Type;
22+
import org.xchange.coinegg.dto.marketdata.CoinEggTrades.CoinEggTrade;
23+
24+
public class CoinEggAdapters {
25+
26+
public static Ticker adaptTicker(CoinEggTicker coinEggTicker, CurrencyPair currencyPair) {
27+
BigDecimal last = coinEggTicker.getLast();
28+
BigDecimal bid = coinEggTicker.getSell();
29+
BigDecimal ask = coinEggTicker.getBuy();
30+
BigDecimal high = coinEggTicker.getHigh();
31+
BigDecimal low = coinEggTicker.getLow();
32+
BigDecimal volume = coinEggTicker.getVolume();
33+
34+
Ticker ticker = new Ticker.Builder()
35+
.currencyPair(currencyPair)
36+
.last(last)
37+
.bid(bid)
38+
.ask(ask)
39+
.high(high)
40+
.low(low)
41+
.volume(volume)
42+
.build();
43+
44+
return ticker;
45+
}
46+
47+
public static LimitOrder adaptOrder(CoinEggOrder coinEggOrder, CurrencyPair currencyPair) {
48+
49+
OrderType type = coinEggOrder.getType() == Type.BUY ? OrderType.ASK : OrderType.BID;
50+
Date timestamp = DateUtils.fromMillisUtc(coinEggOrder.getTimestamp());
51+
String id = String.valueOf(coinEggOrder.getTimestamp());
52+
BigDecimal amount = coinEggOrder.getAmount();
53+
BigDecimal price = coinEggOrder.getPrice();
54+
55+
LimitOrder order = new LimitOrder.Builder(type, currencyPair)
56+
.id(id)
57+
.timestamp(timestamp)
58+
.originalAmount(amount)
59+
.limitPrice(price)
60+
.build();
61+
62+
return order;
63+
}
64+
65+
public static OrderBook adaptOrders(CoinEggOrder[] coinEggOrders, CurrencyPair currencyPair) {
66+
List<LimitOrder> asks = Stream.of(coinEggOrders)
67+
.filter(o -> o.getType() == Type.BUY)
68+
.map(o -> adaptOrder(o, currencyPair))
69+
.collect(Collectors.toList());
70+
71+
List<LimitOrder> bids = Stream.of(coinEggOrders)
72+
.filter(o -> o.getType() == Type.SELL)
73+
.map(o -> adaptOrder(o, currencyPair))
74+
.collect(Collectors.toList());
75+
76+
return new OrderBook(null, asks, bids);
77+
}
78+
79+
public static Trade adaptTrade(CoinEggTrade coinEggTrade, OrderType type, CurrencyPair currencyPair) {
80+
return new Trade.Builder()
81+
.currencyPair(currencyPair)
82+
.id(String.valueOf(coinEggTrade.hashCode()))
83+
.type(type)
84+
.price(coinEggTrade.getPrice())
85+
.originalAmount(coinEggTrade.getQuantity())
86+
.build();
87+
}
88+
89+
public static Trades adaptTrades(CoinEggTrades coinEggTrades, CurrencyPair currencyPair) {
90+
List<Trade> trades = new ArrayList<Trade>();
91+
92+
trades.addAll(Stream.of(coinEggTrades.getAsks())
93+
.map(t -> adaptTrade(t, OrderType.ASK, currencyPair))
94+
.collect(Collectors.toList()));
95+
96+
trades.addAll(Stream.of(coinEggTrades.getBids())
97+
.map(t -> adaptTrade(t, OrderType.BID, currencyPair))
98+
.collect(Collectors.toList()));
99+
100+
return new Trades(trades);
101+
}
102+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.xchange.coinegg;
2+
3+
import java.io.IOException;
4+
5+
import javax.ws.rs.Consumes;
6+
import javax.ws.rs.FormParam;
7+
import javax.ws.rs.POST;
8+
import javax.ws.rs.Path;
9+
import javax.ws.rs.Produces;
10+
import javax.ws.rs.core.MediaType;
11+
12+
import org.xchange.coinegg.dto.accounts.CoinEggBalance;
13+
14+
import si.mazi.rescu.ParamsDigest;
15+
16+
@Path("api/v1")
17+
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
18+
@Produces(MediaType.APPLICATION_JSON)
19+
public interface CoinEggAuthenticated {
20+
21+
@POST
22+
@Path("balance")
23+
CoinEggBalance getBalance(@FormParam("key") String apiKey, @FormParam("nonce") long nonce, @FormParam("signature") ParamsDigest signer) throws IOException;
24+
25+
26+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.xchange.coinegg;
2+
3+
import org.knowm.xchange.BaseExchange;
4+
import org.knowm.xchange.Exchange;
5+
import org.knowm.xchange.ExchangeSpecification;
6+
import org.knowm.xchange.exceptions.NotAvailableFromExchangeException;
7+
import org.knowm.xchange.service.account.AccountService;
8+
import org.knowm.xchange.service.trade.TradeService;
9+
import org.knowm.xchange.utils.nonce.CurrentTimeNonceFactory;
10+
import org.xchange.coinegg.service.CoinEggMarketDataService;
11+
12+
import si.mazi.rescu.SynchronizedValueFactory;
13+
14+
public class CoinEggExchange extends BaseExchange implements Exchange {
15+
16+
private final SynchronizedValueFactory<Long> nonceFactory = new CurrentTimeNonceFactory();
17+
18+
@Override
19+
protected void initServices() {
20+
this.marketDataService = new CoinEggMarketDataService(this);
21+
}
22+
23+
@Override
24+
public SynchronizedValueFactory<Long> getNonceFactory() {
25+
return nonceFactory;
26+
}
27+
28+
@Override
29+
public ExchangeSpecification getDefaultExchangeSpecification() {
30+
ExchangeSpecification exchangeSpecification = new ExchangeSpecification(this.getClass().getCanonicalName());
31+
exchangeSpecification.setSslUri("https://api.coinegg.com");
32+
exchangeSpecification.setHost("http://api.coinegg.com");
33+
exchangeSpecification.setPort(80);
34+
exchangeSpecification.setExchangeName("CoinEgg");
35+
exchangeSpecification.setExchangeDescription("CoinEgg is a Bitcoin exchange based in the United Kingdom.");
36+
37+
return exchangeSpecification;
38+
}
39+
40+
@Override
41+
public TradeService getTradeService() {
42+
throw new NotAvailableFromExchangeException();
43+
}
44+
45+
@Override
46+
public AccountService getAccountService() {
47+
throw new NotAvailableFromExchangeException();
48+
}
49+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.xchange.coinegg;
2+
3+
import java.security.MessageDigest;
4+
import java.security.NoSuchAlgorithmException;
5+
6+
import javax.xml.bind.DatatypeConverter;
7+
8+
import org.knowm.xchange.currency.CurrencyPair;
9+
10+
public class CoinEggUtils {
11+
12+
private static MessageDigest md5Digest;
13+
14+
static {
15+
try {
16+
md5Digest = MessageDigest.getInstance("MD5");
17+
} catch (NoSuchAlgorithmException e) {
18+
e.printStackTrace();
19+
}
20+
}
21+
22+
public static String toBaseCoin(CurrencyPair currencyPair) {
23+
return currencyPair.base.getCurrencyCode().toLowerCase();
24+
}
25+
26+
public static String toHexString(byte[] data) {
27+
return DatatypeConverter.printHexBinary(data);
28+
}
29+
30+
public static String toMD5Hash(String data) {
31+
return toHexString(md5Digest.digest(data.getBytes()));
32+
}
33+
34+
}

0 commit comments

Comments
 (0)