1 package org.oxerr.okcoin.rest.service;
2
3 import java.io.IOException;
4 import java.math.BigDecimal;
5 import java.util.Arrays;
6 import java.util.stream.Collectors;
7 import java.util.stream.StreamSupport;
8
9 import org.knowm.xchange.Exchange;
10 import org.knowm.xchange.currency.CurrencyPair;
11 import org.knowm.xchange.dto.Order.OrderType;
12 import org.oxerr.okcoin.rest.OKCoinException;
13 import org.oxerr.okcoin.rest.dto.BatchTradeResult;
14 import org.oxerr.okcoin.rest.dto.BorrowOrderInfo;
15 import org.oxerr.okcoin.rest.dto.BorrowResult;
16 import org.oxerr.okcoin.rest.dto.BorrowsInfo;
17 import org.oxerr.okcoin.rest.dto.CancelOrderResult;
18 import org.oxerr.okcoin.rest.dto.IcebergOrder;
19 import org.oxerr.okcoin.rest.dto.IcebergOrderHistory;
20 import org.oxerr.okcoin.rest.dto.OrderData;
21 import org.oxerr.okcoin.rest.dto.OrderFee;
22 import org.oxerr.okcoin.rest.dto.OrderHistory;
23 import org.oxerr.okcoin.rest.dto.OrderResult;
24 import org.oxerr.okcoin.rest.dto.Result;
25 import org.oxerr.okcoin.rest.dto.Trade;
26 import org.oxerr.okcoin.rest.dto.TradeResult;
27 import org.oxerr.okcoin.rest.dto.Type;
28 import org.oxerr.okcoin.rest.dto.UnrepaymentsInfo;
29 import org.oxerr.okcoin.rest.service.web.LoginRequiredException;
30 import org.oxerr.okcoin.rest.service.web.OKCoinClientException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.fasterxml.jackson.databind.ObjectMapper;
35 import com.fasterxml.jackson.databind.SerializationFeature;
36
37
38
39
40 public class OKCoinTradeServiceRaw extends OKCoinBaseTradeService {
41
42 private static final String METHOD_TRADE = "trade";
43 private static final String METHOD_CANCEL_ORDER = "cancel_order";
44 private static final String METHOD_GET_ORDER = "order_info";
45
46 private final Logger log = LoggerFactory.getLogger(OKCoinTradeServiceRaw.class);
47
48 private final ObjectMapper mapper;
49
50 protected OKCoinTradeServiceRaw(Exchange exchange) {
51 super(exchange);
52
53 mapper = new ObjectMapper();
54 mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
55 }
56
57 public Trade[] getTradeHistory(String symbol, Long since) throws IOException {
58 return okCoin.getTradeHistory(apiKey, symbol, since, sign);
59 }
60
61 public TradeResult trade(String symbol, Type type, BigDecimal price,
62 BigDecimal amount) throws OKCoinException, IOException {
63 sleep(METHOD_TRADE);
64 TradeResult tradeResult = okCoin.trade(apiKey, symbol, type, price, amount, sign);
65 updateLast(METHOD_TRADE);
66
67 return tradeResult;
68 }
69
70 public BatchTradeResult batchTrade(String symbol, Type type,
71 OrderData[] orders) throws OKCoinException, IOException {
72 String ordersData = mapper.writeValueAsString(orders);
73 return okCoin.batchTrade(apiKey, symbol, type, ordersData, sign);
74 }
75
76 public CancelOrderResult cancelOrder(String symbol, long... orderIds)
77 throws OKCoinException, IOException {
78 sleep(METHOD_CANCEL_ORDER);
79 String orderId = Arrays.stream(orderIds)
80 .mapToObj(id -> String.valueOf(id))
81 .collect(Collectors.joining(","));
82 CancelOrderResult result = okCoin.cancelOrder(apiKey, symbol, orderId, sign);
83 updateLast(METHOD_CANCEL_ORDER);
84
85 return result;
86 }
87
88 public OrderResult getOrder(String symbol, long orderId)
89 throws OKCoinException, IOException {
90 sleep(METHOD_GET_ORDER);
91 OrderResult orderResult = okCoin.getOrder(apiKey, symbol, orderId, sign);
92 updateLast(METHOD_GET_ORDER);
93
94 return orderResult;
95 }
96
97 public OrderResult getOrders(String symbol, int type, long[] orderIds)
98 throws OKCoinException, IOException {
99 String orderId = Arrays.stream(orderIds)
100 .mapToObj(id -> String.valueOf(id))
101 .collect(Collectors.joining(","));
102 return okCoin.getOrders(apiKey, symbol, type, orderId, sign);
103 }
104
105 public OrderResult getOrders(String symbol, int type, Long[] orderIds)
106 throws OKCoinException, IOException {
107 String orderId = Arrays.stream(orderIds)
108 .map(id -> id.toString())
109 .collect(Collectors.joining(","));
110 return okCoin.getOrders(apiKey, symbol, type, orderId, sign);
111 }
112
113 public OrderResult getOrders(String symbol, int type,
114 Iterable<Long> orderIds) throws OKCoinException, IOException {
115 String orderId = StreamSupport.stream(orderIds.spliterator(), false)
116 .map(id -> id.toString())
117 .collect(Collectors.joining(","));
118 return okCoin.getOrders(apiKey, symbol, type, orderId, sign);
119 }
120
121 public OrderHistory getOrderHistory(String symbol, int status,
122 int currentPage, int pageLength) throws OKCoinException,
123 IOException {
124 return okCoin.getOrderHistory(apiKey, symbol, status, currentPage,
125 pageLength, sign);
126 }
127
128 public IcebergOrderHistory getOpenIcebergOrders(CurrencyPair currencyPair)
129 throws IOException {
130 int symbol = toSymbol(currencyPair);
131 return getOpenIcebergOrders(symbol);
132 }
133
134 private IcebergOrderHistory getOpenIcebergOrders(int symbol) throws IOException {
135 int sign = 1;
136 return getIcebergOrders(symbol, sign, null);
137 }
138
139 public IcebergOrderHistory getIcebergOrderHistory(CurrencyPair currencyPair, Integer page)
140 throws IOException {
141 int symbol = toSymbol(currencyPair);
142 int sign = 2;
143 return getIcebergOrders(symbol, sign, page);
144 }
145
146 private IcebergOrderHistory getIcebergOrders(int symbol, int sign, Integer page)
147 throws IOException {
148 int retry = 0;
149
150 while (true) {
151 try {
152 log.debug("Trying to get iceberge open orders.");
153 return okCoinClient.getIcebergOrders(symbol, 5, sign, 2, page);
154 } catch (LoginRequiredException e) {
155 if (++retry <= this.loginMaxRetryTimes) {
156 log.debug("Not logged in. Try to login. Retry: {}.", retry);
157 okCoinClient.login();
158 } else {
159 throw e;
160 }
161 }
162 }
163 }
164
165 public long placeIcebergOrder(
166 CurrencyPair currencyPair,
167 OrderType type,
168 BigDecimal tradeValue,
169 BigDecimal singleAvg,
170 BigDecimal depthRange,
171 BigDecimal protectedPrice)
172 throws OKCoinClientException, IOException {
173 int symbol = toSymbol(currencyPair);
174 Result result = submitContinuousEntrust(
175 symbol,
176 type == OrderType.BID ? 1 : 2,
177 tradeValue, singleAvg, depthRange, protectedPrice);
178 log.debug("result: {}", result);
179 if (result.getResultCode() != 0) {
180 throw new OKCoinClientException(result);
181 }
182 IcebergOrder[] icebergOrders = getOpenIcebergOrders(symbol).getOrders();
183 return icebergOrders[0].getId();
184 }
185
186 private Result submitContinuousEntrust(int symbol, int type,
187 BigDecimal tradeValue, BigDecimal singleAvg, BigDecimal depthRange,
188 BigDecimal protePrice) throws IOException {
189 int retry = 0;
190
191 while (true) {
192 try {
193 return okCoinClient.submitContinuousEntrust(symbol, type, tradeValue, singleAvg, depthRange, protePrice);
194 } catch (LoginRequiredException e) {
195 if (++retry <= this.loginMaxRetryTimes) {
196 okCoinClient.login();
197 } else {
198 throw e;
199 }
200 }
201 }
202 }
203
204 public boolean cancelIcebergeOrder(CurrencyPair currencyPair, long id)
205 throws IOException {
206 int symbol = toSymbol(currencyPair);
207 return cancelContinuousEntrust(symbol, id);
208 }
209
210 private boolean cancelContinuousEntrust(int symbol, long id) throws IOException {
211 int retry = 0;
212
213 while (true) {
214 try {
215 return okCoinClient.cancelContinuousEntrust(symbol, id);
216 } catch (LoginRequiredException e) {
217 if (++retry <= this.loginMaxRetryTimes) {
218 okCoinClient.login();
219 } else {
220 throw e;
221 }
222 }
223 }
224 }
225
226 private int toSymbol(CurrencyPair currencyPair) {
227 return currencyPair.base.getCurrencyCode().equals("BTC") ? 0 : 1;
228 }
229
230 public OrderFee getOrderFee(String symbol, long orderId)
231 throws OKCoinException, IOException {
232 return okCoin.getOrderFee(apiKey, symbol, orderId, sign);
233 }
234
235 public BorrowsInfo getBorrowsInfo(String symbol) throws OKCoinException,
236 IOException {
237 return okCoin.getBorrowsInfo(apiKey, symbol, sign);
238 }
239
240 public BorrowResult borrowMoney(String symbol, String days, BigDecimal amount,
241 BigDecimal rate) throws OKCoinException, IOException {
242 return okCoin.borrowMoney(apiKey, symbol, days, amount, rate, sign);
243 }
244
245 public BorrowResult cancelBorrow(String symbol, long borrowId)
246 throws OKCoinException, IOException {
247 return okCoin.cancelBorrow(apiKey, symbol, borrowId, sign);
248 }
249
250 public BorrowOrderInfo getBorrowOrderInfo(long borrowId)
251 throws OKCoinException, IOException {
252 return okCoin.getBorrowOrderInfo(apiKey, borrowId, sign);
253 }
254
255 public BorrowResult repay(long borrowId) throws OKCoinException,
256 IOException {
257 return okCoin.repay(apiKey, borrowId, sign);
258 }
259
260 public UnrepaymentsInfo getUnrepaymentsInfo(String symbol, int currentPage,
261 int pageLength) throws OKCoinException, IOException {
262 return okCoin.getUnrepaymentsInfo(apiKey, symbol, currentPage, pageLength, sign);
263 }
264
265 }