View Javadoc
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   * Raw trade service.
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; // open orders;
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; // order history
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 }