├── README.md ├── api_java ├── pom.xml ├── readme.md └── src │ ├── main │ └── java │ │ └── com │ │ └── bitcoke │ │ └── api │ │ ├── ApiUtil.java │ │ ├── MarketRestApi.java │ │ ├── TradeRestApi.java │ │ └── enums │ │ ├── ApiTimeInForce.java │ │ ├── Currency.java │ │ ├── Indices.java │ │ ├── OrderSide.java │ │ ├── OrderType.java │ │ ├── PositionSide.java │ │ ├── Symbol.java │ │ └── TriggerPriceType.java │ └── test │ └── java │ └── com │ └── bitcoke │ └── api │ └── examples │ ├── MarketRestApiExample.java │ ├── MarketWsExample.java │ ├── TradeRestApiExample.java │ └── TradeWsExample.java └── api_py ├── __pycache__ ├── clientbase.cpython-38.pyc ├── const.cpython-38.pyc ├── market_api.cpython-38.pyc ├── trading_api.cpython-38.pyc └── wallet_api.cpython-38.pyc ├── clientbase.py ├── const.py ├── example.py ├── market_api.py ├── readme.md ├── trading_api.py ├── wallet_api.py └── websocket_example.py /README.md: -------------------------------------------------------------------------------- 1 | # BitCoke Api 2 | 3 | ### Document 4 | https://www.bitcoke.com/api-doc/ 5 | 6 | ### Api Demo 7 | |list|language| 8 | |----|:--------:| 9 | |api-py|Python| 10 | |api-java|Java| 11 | -------------------------------------------------------------------------------- /api_java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bitcoke.sdk 8 | bitcoke-demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 1.8 13 | 14 | 15 | 16 | 17 | com.squareup.okhttp3 18 | okhttp 19 | 3.12.1 20 | 21 | 22 | 23 | commons-codec 24 | commons-codec 25 | 1.13 26 | 27 | 28 | 29 | org.java-websocket 30 | Java-WebSocket 31 | 1.5.0 32 | 33 | 34 | 35 | com.google.code.gson 36 | gson 37 | 2.8.0 38 | 39 | 40 | 41 | org.slf4j 42 | slf4j-simple 43 | 1.7.25 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /api_java/readme.md: -------------------------------------------------------------------------------- 1 | 2 | ### Requirements 3 | 4 | Building the API client library requires: 5 | 6 | ``` 7 | Java 1.8 8 | Maven 9 | ``` 10 | 11 | ### Api Demo 12 | 13 | * #### RestApi 14 | 15 | ```src/main/java/com.bitcoke.api``` is the simple wrap for rest api using okhttp3. 16 | 17 | ```src/test/java/com.bitcoke.api.examples``` is the simple example for api invoke. 18 | 19 | Run ```MarketRestApiExample.java``` to view the example for market rest api. 20 | 21 | Run ```TradeRestApiExample.java``` to view the example for trade rest api. 22 | 23 | 24 | * #### WebSocketApi 25 | 26 | Run ```MarketWsExample.java``` to view the example for market websocket api. 27 | 28 | Run ```TradeWsExample.java``` to view the example for trade websocket api. 29 | 30 | 31 | ### Document 32 | 33 | https://www.bitcoke.com/api-doc/ 34 | 35 | 36 | This is a simple example. We strongly recommend that you implement it yourself. 37 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/ApiUtil.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api; 2 | 3 | import okhttp3.Headers; 4 | import okhttp3.OkHttpClient; 5 | import okhttp3.Request; 6 | import okhttp3.Response; 7 | import org.apache.commons.codec.digest.DigestUtils; 8 | 9 | abstract class ApiUtil { 10 | 11 | private static final OkHttpClient client = new OkHttpClient(); 12 | 13 | 14 | public static String callSync(Request request) throws Exception { 15 | String str; 16 | Response response = client.newCall(request).execute(); 17 | str = response.body().string(); 18 | response.close(); 19 | return str; 20 | } 21 | 22 | private static String getSignature(String apiSecret, String requestMethod, String path, Long expires) { 23 | return DigestUtils.sha256Hex(apiSecret + requestMethod + path + expires.toString()); 24 | } 25 | 26 | public static Headers getHeaders(String apiKey, String apiSecret, String requestMethod, String apiPath) { 27 | Long expires = System.currentTimeMillis() / 1000 + 5; 28 | Headers.Builder builder = new Headers.Builder(); 29 | builder.add("Content-Type", "application/json;charset=UTF-8") 30 | .add("apiKey", apiKey) 31 | .add("expires", expires.toString()) 32 | .add("signature", getSignature(apiSecret, requestMethod, apiPath, expires)); 33 | return builder.build(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/MarketRestApi.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api; 2 | 3 | import com.sun.deploy.util.StringUtils; 4 | import okhttp3.HttpUrl; 5 | import okhttp3.Request; 6 | 7 | import java.util.List; 8 | 9 | public class MarketRestApi { 10 | 11 | private final String BASE_URL = "http://api.bitcoke.com"; 12 | 13 | private final String REF_DATA = "/api/basic/refData"; 14 | private final String LAST_PRICE = "/api/basic/lastPrice"; 15 | private final String PRICE = "/api/index/price"; 16 | private final String DEPTH = "/api/depth/depth"; 17 | private final String TRADES = "/api/depth/trades"; 18 | private final String QUOTES = "/api/depth/quotes"; 19 | private final String KLINE_BY_INDEX = "/api/kLine/byIndex"; 20 | private final String KLINE_BY_TIME = "/api/kLine/byTime"; 21 | private final String KLINE_LATEST = "/api/kLine/latest"; 22 | private final String KLINE_LATEST_PERIOD = "/api/kLine/latestPeriod"; 23 | private final String KLINE_FUNDING_RATE = "/api/kLine/fundingRate"; 24 | private final String KLINE_TRADE_STATISTICS = "/api/kLine/tradeStatistics"; 25 | private final String KLINE_OPEN_INTEREST = "/api/kLine/openInterest"; 26 | 27 | // Query basic refData info 28 | public String refData() throws Exception { 29 | String url = BASE_URL + REF_DATA; 30 | Request.Builder builder = new Request.Builder(); 31 | Request request = builder.url(url).build(); 32 | return ApiUtil.callSync(request); 33 | } 34 | 35 | // Query last price of symbol(s) 36 | public String lastPrice(List symbols) throws Exception { 37 | String url = BASE_URL + LAST_PRICE; 38 | Request.Builder builder = new Request.Builder(); 39 | Request request = builder.url(url).build(); 40 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 41 | urlBuilder.addQueryParameter("symbols", StringUtils.join(symbols, ",")); 42 | builder.url(urlBuilder.build()); 43 | return ApiUtil.callSync(builder.build()); 44 | } 45 | 46 | // Query index price of instrument 47 | public String price(List symbols) throws Exception { 48 | String url = BASE_URL + PRICE; 49 | Request.Builder builder = new Request.Builder(); 50 | Request request = builder.url(url).build(); 51 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 52 | urlBuilder.addQueryParameter("symbols", StringUtils.join(symbols, ",")); 53 | builder.url(urlBuilder.build()); 54 | return ApiUtil.callSync(builder.build()); 55 | } 56 | 57 | // Query market depth of instrument 58 | public String depth(String symbol) throws Exception { 59 | String url = BASE_URL + DEPTH; 60 | Request.Builder builder = new Request.Builder(); 61 | Request request = builder.url(url).build(); 62 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 63 | urlBuilder.addQueryParameter("symbol", symbol); 64 | builder.url(urlBuilder.build()); 65 | return ApiUtil.callSync(builder.build()); 66 | } 67 | 68 | // Query trades of instrument 69 | public String trades(String symbol) throws Exception { 70 | String url = BASE_URL + TRADES; 71 | Request.Builder builder = new Request.Builder(); 72 | Request request = builder.url(url).build(); 73 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 74 | urlBuilder.addQueryParameter("symbol", symbol); 75 | builder.url(urlBuilder.build()); 76 | return ApiUtil.callSync(builder.build()); 77 | } 78 | 79 | // Query market depth & trades of instrument 80 | public String quotes(String symbol) throws Exception { 81 | String url = BASE_URL + QUOTES; 82 | Request.Builder builder = new Request.Builder(); 83 | Request request = builder.url(url).build(); 84 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 85 | urlBuilder.addQueryParameter("symbol", symbol); 86 | builder.url(urlBuilder.build()); 87 | return ApiUtil.callSync(builder.build()); 88 | } 89 | 90 | // Query K line of instrument by index and step 91 | public String kLineByIndex(String symbol, String type, Integer step, Integer from) throws Exception { 92 | String url = BASE_URL + KLINE_BY_INDEX; 93 | Request.Builder builder = new Request.Builder(); 94 | Request request = builder.url(url).build(); 95 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 96 | urlBuilder.addQueryParameter("symbol", symbol); 97 | urlBuilder.addQueryParameter("type", type); 98 | urlBuilder.addQueryParameter("step", step.toString()); 99 | urlBuilder.addQueryParameter("from", from.toString()); 100 | builder.url(urlBuilder.build()); 101 | return ApiUtil.callSync(builder.build()); 102 | } 103 | 104 | // Query K line of instrument by million seconds of key time 105 | public String kLineByTime(String symbol, String type, Integer step, Long from) throws Exception { 106 | String url = BASE_URL + KLINE_BY_TIME; 107 | Request.Builder builder = new Request.Builder(); 108 | Request request = builder.url(url).build(); 109 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 110 | urlBuilder.addQueryParameter("symbol", symbol); 111 | urlBuilder.addQueryParameter("type", type); 112 | urlBuilder.addQueryParameter("step", step.toString()); 113 | if (from != null) urlBuilder.addQueryParameter("from", from.toString()); 114 | builder.url(urlBuilder.build()); 115 | return ApiUtil.callSync(builder.build()); 116 | } 117 | 118 | // Retrieve the latest K line of Instrument 119 | public String kLineLatest(String symbol, String type) throws Exception { 120 | String url = BASE_URL + KLINE_LATEST; 121 | Request.Builder builder = new Request.Builder(); 122 | Request request = builder.url(url).build(); 123 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 124 | urlBuilder.addQueryParameter("symbol", symbol); 125 | urlBuilder.addQueryParameter("type", type); 126 | builder.url(urlBuilder.build()); 127 | return ApiUtil.callSync(builder.build()); 128 | } 129 | 130 | // Retrieve K line(s) of Instrument since the last K line time(million seconds), Maximum 100 records can be returned 131 | public String kLineLatestPeriod(String symbol, String type, Long lastKTime) throws Exception { 132 | String url = BASE_URL + KLINE_LATEST_PERIOD; 133 | Request.Builder builder = new Request.Builder(); 134 | Request request = builder.url(url).build(); 135 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 136 | urlBuilder.addQueryParameter("symbol", symbol); 137 | urlBuilder.addQueryParameter("type", type); 138 | if (lastKTime != null) urlBuilder.addQueryParameter("lastKTime", lastKTime.toString()); 139 | builder.url(urlBuilder.build()); 140 | return ApiUtil.callSync(builder.build()); 141 | } 142 | 143 | // Latest funding rate 144 | public String fundingRate(List symbols) throws Exception { 145 | String url = BASE_URL + KLINE_FUNDING_RATE; 146 | Request.Builder builder = new Request.Builder(); 147 | Request request = builder.url(url).build(); 148 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 149 | urlBuilder.addQueryParameter("symbols", StringUtils.join(symbols, ",")); 150 | builder.url(urlBuilder.build()); 151 | return ApiUtil.callSync(builder.build()); 152 | } 153 | 154 | // Trade Statistics in latest 24 hours 155 | public String tradeStatistics(List symbols) throws Exception { 156 | String url = BASE_URL + KLINE_TRADE_STATISTICS; 157 | Request.Builder builder = new Request.Builder(); 158 | Request request = builder.url(url).build(); 159 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 160 | urlBuilder.addQueryParameter("symbols", StringUtils.join(symbols, ",")); 161 | builder.url(urlBuilder.build()); 162 | return ApiUtil.callSync(builder.build()); 163 | } 164 | 165 | // Total Open Position In Exchange 166 | public String openInterest(String symbol) throws Exception { 167 | String url = BASE_URL + KLINE_OPEN_INTEREST; 168 | Request.Builder builder = new Request.Builder(); 169 | Request request = builder.url(url).build(); 170 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 171 | urlBuilder.addQueryParameter("symbol", symbol); 172 | builder.url(urlBuilder.build()); 173 | return ApiUtil.callSync(builder.build()); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/TradeRestApi.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api; 2 | 3 | import okhttp3.*; 4 | 5 | public class TradeRestApi { 6 | 7 | private final String BASE_URL = "http://api.bitcoke.com/trade"; 8 | 9 | private final String HTTP_GET = "GET"; 10 | private final String HTTP_POST = "POST"; 11 | 12 | private final String QUERY_ACCOUNT = "/api/trade/queryAccounts"; 13 | private final String QUERY_ACTIVE_ORDERS = "/api/trade/queryActiveOrders"; 14 | private final String QUERY_ORDERS = "/api/trade/queryOrders"; 15 | private final String QUERY_ORDERS_PRO = "/api/trade/queryOrdersPro"; 16 | private final String QUERY_ORDER_BY_ID = "/api/trade/queryOrderById"; 17 | private final String QUERY_POSITION = "/api/trade/queryPosition"; 18 | private final String LEDGER = "/api/trade/ledger"; 19 | private final String ENTER_ORDER = "/api/trade/enterOrder"; 20 | private final String CANCEL_ORDER = "/api/trade/cancelOrder"; 21 | private final String AMEND_ORDER = "/api/trade/amendOrder"; 22 | private final String CLOSE_POSITION = "/api/trade/closePosition"; 23 | private final String CHANGE_POS_LEVERAGE = "/api/trade/changePosLeverage"; 24 | private final String RISK_SETTING = "/api/trade/riskSetting"; 25 | private final String SWITCH_POS_SIDE = "/api/trade/switchPosSide"; 26 | private final String SWITCH_TO_CROSS = "/api/trade/switchToCross"; 27 | 28 | private String apiKey; 29 | private String apiSecret; 30 | 31 | public TradeRestApi(String apiKey, String apiSecret) { 32 | this.apiKey = apiKey; 33 | this.apiSecret = apiSecret; 34 | } 35 | 36 | // Request accounts of user by api key 37 | public String queryAccount() throws Exception { 38 | String url = BASE_URL + QUERY_ACCOUNT; 39 | Request.Builder builder = new Request.Builder(); 40 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, QUERY_ACCOUNT)); 41 | Request request = builder.url(url).build(); 42 | return ApiUtil.callSync(request); 43 | } 44 | 45 | // Request active orders of user by api key 46 | public String queryActiveOrders(String symbol) throws Exception { 47 | String url = BASE_URL + QUERY_ACTIVE_ORDERS; 48 | Request.Builder builder = new Request.Builder(); 49 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, QUERY_ACTIVE_ORDERS)); 50 | Request request = builder.url(url).build(); 51 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 52 | urlBuilder.addQueryParameter("symbol", symbol); 53 | builder.url(urlBuilder.build()); 54 | return ApiUtil.callSync(builder.build()); 55 | } 56 | 57 | // Request orders of user by api key 58 | // will be decommissioned soon, please use queryOrdersPro 59 | public String queryOrders(String prevId) throws Exception { 60 | String url = BASE_URL + QUERY_ORDERS; 61 | Request.Builder builder = new Request.Builder(); 62 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, QUERY_ORDERS)); 63 | Request request = builder.url(url).build(); 64 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 65 | if (prevId != null) urlBuilder.addQueryParameter("prevId", prevId); 66 | builder.url(urlBuilder.build()); 67 | return ApiUtil.callSync(builder.build()); 68 | } 69 | 70 | // Request orders of user by api key 71 | public String queryOrdersPro(Long prevTimeMillis) throws Exception { 72 | String url = BASE_URL + QUERY_ORDERS_PRO; 73 | Request.Builder builder = new Request.Builder(); 74 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, QUERY_ORDERS_PRO)); 75 | Request request = builder.url(url).build(); 76 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 77 | if (prevTimeMillis != null) urlBuilder.addQueryParameter("prevTimeMillis", prevTimeMillis.toString()); 78 | builder.url(urlBuilder.build()); 79 | return ApiUtil.callSync(builder.build()); 80 | } 81 | 82 | // Request order by id 83 | public String queryOrderById(String orderId) throws Exception { 84 | String url = BASE_URL + QUERY_ORDER_BY_ID; 85 | Request.Builder builder = new Request.Builder(); 86 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, QUERY_ORDER_BY_ID)); 87 | Request request = builder.url(url).build(); 88 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 89 | if (orderId != null) urlBuilder.addQueryParameter("orderId", orderId); 90 | builder.url(urlBuilder.build()); 91 | return ApiUtil.callSync(builder.build()); 92 | } 93 | 94 | // Request position of user by api key 95 | public String queryPosition() throws Exception { 96 | String url = BASE_URL + QUERY_POSITION; 97 | Request.Builder builder = new Request.Builder(); 98 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, QUERY_POSITION)); 99 | Request request = builder.url(url).build(); 100 | return ApiUtil.callSync(request); 101 | } 102 | 103 | // Request trade ledger of user by api key 104 | public String ledger(String currency, String from, Long pageNo, Long pageSize) throws Exception { 105 | String url = BASE_URL + LEDGER; 106 | Request.Builder builder = new Request.Builder(); 107 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_GET, LEDGER)); 108 | Request request = builder.url(url).build(); 109 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 110 | urlBuilder.addQueryParameter("currency", currency); 111 | urlBuilder.addQueryParameter("from", from); 112 | urlBuilder.addQueryParameter("pageNo", pageNo.toString()); 113 | urlBuilder.addQueryParameter("pageSize", pageSize.toString()); 114 | builder.url(urlBuilder.build()); 115 | return ApiUtil.callSync(builder.build()); 116 | } 117 | 118 | // Enter order by complete parameters 119 | public String enterOrder(String currency, String symbol, Boolean openPosition, String side, 120 | Double qty, String orderType, Double price, Boolean hidden, 121 | Double showQty, Double stopLossPrice, Double stopWinPrice, 122 | Double stopWinType, String tif, Double trailingStop, Double triggerPrice, 123 | String triggerType) throws Exception { 124 | String url = BASE_URL + ENTER_ORDER; 125 | Request.Builder builder = new Request.Builder(); 126 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, ENTER_ORDER)); 127 | Request request = builder.url(url).build(); 128 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 129 | urlBuilder.addQueryParameter("currency", currency); 130 | urlBuilder.addQueryParameter("symbol", symbol); 131 | urlBuilder.addQueryParameter("openPosition", openPosition.toString()); 132 | urlBuilder.addQueryParameter("side", side); 133 | urlBuilder.addQueryParameter("qty", qty.toString()); 134 | urlBuilder.addQueryParameter("orderType", orderType); 135 | if (price != null) urlBuilder.addQueryParameter("price", price.toString()); 136 | if (hidden != null) urlBuilder.addQueryParameter("hidden", hidden.toString()); 137 | if (showQty != null) urlBuilder.addQueryParameter("showQty", showQty.toString()); 138 | if (stopLossPrice != null) urlBuilder.addQueryParameter("stopLossPrice", stopLossPrice.toString()); 139 | if (stopWinPrice != null) urlBuilder.addQueryParameter("stopWinPrice", stopWinPrice.toString()); 140 | if (stopWinType != null) urlBuilder.addQueryParameter("stopWinType", stopWinType.toString()); 141 | if (tif != null) urlBuilder.addQueryParameter("tif", tif); 142 | if (trailingStop != null) urlBuilder.addQueryParameter("trailingStop", trailingStop.toString()); 143 | if (triggerPrice != null) urlBuilder.addQueryParameter("triggerPrice", triggerPrice.toString()); 144 | if (triggerType != null) urlBuilder.addQueryParameter("triggerType", triggerType); 145 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 146 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 147 | return ApiUtil.callSync(builder.build()); 148 | } 149 | 150 | // Enter order by simplified parameters 151 | public String enterOrder(String currency, String symbol, Boolean openPosition, String side, Double qty, 152 | String orderType, Double price) throws Exception { 153 | return enterOrder(currency, symbol, openPosition, side, qty, orderType, price, null, null, null, 154 | null, null, null, null, null, null); 155 | } 156 | 157 | // Cancel order by orderId 158 | public String cancelOrder(String orderId) throws Exception { 159 | String url = BASE_URL + CANCEL_ORDER; 160 | Request.Builder builder = new Request.Builder(); 161 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, CANCEL_ORDER)); 162 | Request request = builder.url(url).build(); 163 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 164 | urlBuilder.addQueryParameter("orderId", orderId); 165 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 166 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 167 | return ApiUtil.callSync(builder.build()); 168 | } 169 | 170 | public String amendOrder(String orderId, Double price, Double qty, Double stopLossPrice, 171 | Double stopWinPrice, Double trailingStop, Double triggerPrice) throws Exception { 172 | String url = BASE_URL + AMEND_ORDER; 173 | Request.Builder builder = new Request.Builder(); 174 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, AMEND_ORDER)); 175 | Request request = builder.url(url).build(); 176 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 177 | urlBuilder.addQueryParameter("orderId", orderId); 178 | if (price != null) urlBuilder.addQueryParameter("price", price.toString()); 179 | if (qty != null) urlBuilder.addQueryParameter("qty", qty.toString()); 180 | if (stopLossPrice != null) urlBuilder.addQueryParameter("stopLossPrice", stopLossPrice.toString()); 181 | if (stopWinPrice != null) urlBuilder.addQueryParameter("stopWinPrice", stopWinPrice.toString()); 182 | if (trailingStop != null) urlBuilder.addQueryParameter("trailingStop", trailingStop.toString()); 183 | if (triggerPrice != null) urlBuilder.addQueryParameter("triggerPrice", triggerPrice.toString()); 184 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 185 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 186 | return ApiUtil.callSync(builder.build()); 187 | } 188 | 189 | public String closePosition(String currency, String symbol, String side) throws Exception { 190 | String url = BASE_URL + CLOSE_POSITION; 191 | Request.Builder builder = new Request.Builder(); 192 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, CLOSE_POSITION)); 193 | Request request = builder.url(url).build(); 194 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 195 | urlBuilder.addQueryParameter("currency", currency); 196 | urlBuilder.addQueryParameter("symbol", symbol); 197 | urlBuilder.addQueryParameter("side", side); 198 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 199 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 200 | return ApiUtil.callSync(builder.build()); 201 | } 202 | 203 | // Change position leverage 204 | public String changePosLeverage(String currency, String symbol, Double leverage) throws Exception { 205 | String url = BASE_URL + CHANGE_POS_LEVERAGE; 206 | Request.Builder builder = new Request.Builder(); 207 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, CHANGE_POS_LEVERAGE)); 208 | Request request = builder.url(url).build(); 209 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 210 | urlBuilder.addQueryParameter("currency", currency); 211 | urlBuilder.addQueryParameter("symbol", symbol); 212 | urlBuilder.addQueryParameter("leverage", leverage.toString()); 213 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 214 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 215 | return ApiUtil.callSync(builder.build()); 216 | } 217 | 218 | // Change risk setting of position 219 | public String riskSetting(String currency, String symbol, String side, Double addDeposit, 220 | Double stopLossPrice, Double stopWinPrice, Double stopWinType, 221 | Double trailingStop) throws Exception { 222 | String url = BASE_URL + RISK_SETTING; 223 | Request.Builder builder = new Request.Builder(); 224 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, RISK_SETTING)); 225 | Request request = builder.url(url).build(); 226 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 227 | urlBuilder.addQueryParameter("currency", currency); 228 | urlBuilder.addQueryParameter("symbol", symbol); 229 | urlBuilder.addQueryParameter("side", side); 230 | if (addDeposit != null) urlBuilder.addQueryParameter("addDeposit", addDeposit.toString()); 231 | if (stopLossPrice != null) urlBuilder.addQueryParameter("stopLossPrice", stopLossPrice.toString()); 232 | if (stopWinPrice != null) urlBuilder.addQueryParameter("stopWinPrice", stopWinPrice.toString()); 233 | if (stopWinType != null) urlBuilder.addQueryParameter("stopWinType", stopWinType.toString()); 234 | if (trailingStop != null) urlBuilder.addQueryParameter("trailingStop", trailingStop.toString()); 235 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 236 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 237 | return ApiUtil.callSync(builder.build()); 238 | } 239 | 240 | // Switch position side 241 | public String switchPosSide(String currency, Boolean twoSidePosition) throws Exception { 242 | String url = BASE_URL + SWITCH_POS_SIDE; 243 | Request.Builder builder = new Request.Builder(); 244 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, SWITCH_POS_SIDE)); 245 | Request request = builder.url(url).build(); 246 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 247 | urlBuilder.addQueryParameter("currency", currency); 248 | urlBuilder.addQueryParameter("twoSidePosition", twoSidePosition.toString()); 249 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 250 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 251 | return ApiUtil.callSync(builder.build()); 252 | } 253 | 254 | // Switch to cross position mode 255 | public String switchToCross(String currency) throws Exception { 256 | String url = BASE_URL + SWITCH_TO_CROSS; 257 | Request.Builder builder = new Request.Builder(); 258 | builder.headers(ApiUtil.getHeaders(apiKey, apiSecret, HTTP_POST, SWITCH_TO_CROSS)); 259 | Request request = builder.url(url).build(); 260 | HttpUrl.Builder urlBuilder = request.url().newBuilder(); 261 | urlBuilder.addQueryParameter("currency", currency); 262 | FormBody.Builder formBodyBuilder = new FormBody.Builder(); 263 | builder.url(urlBuilder.build()).post(formBodyBuilder.build()); 264 | return ApiUtil.callSync(builder.build()); 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/ApiTimeInForce.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum ApiTimeInForce { 4 | GOOD_TILL_CANCEL, 5 | IMMEDIATE_OR_CANCEL, 6 | FILL_OR_KILL, 7 | QUEUE_OR_CANCEL, 8 | } 9 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/Currency.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum Currency { 4 | BTC, 5 | EOS, 6 | ETH, 7 | USDT, 8 | } 9 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/Indices.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum Indices { 4 | BTCUSD, 5 | ETHUSD, 6 | EOSUSD, 7 | LTCUSD, 8 | BCHUSD, 9 | } 10 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/OrderSide.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum OrderSide { 4 | Buy, 5 | Sell, 6 | } 7 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/OrderType.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum OrderType { 4 | Limit, 5 | Market, 6 | } 7 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/PositionSide.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum PositionSide { 4 | Long, 5 | Short 6 | } 7 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/Symbol.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum Symbol { 4 | XBTCUSD, 5 | XETHUSD, 6 | XEOSUSD, 7 | XLTCUSD, 8 | XBCHUSD, 9 | } 10 | -------------------------------------------------------------------------------- /api_java/src/main/java/com/bitcoke/api/enums/TriggerPriceType.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.enums; 2 | 3 | public enum TriggerPriceType { 4 | LAST, 5 | INDEX 6 | } 7 | -------------------------------------------------------------------------------- /api_java/src/test/java/com/bitcoke/api/examples/MarketRestApiExample.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.examples; 2 | 3 | import com.bitcoke.api.MarketRestApi; 4 | import com.bitcoke.api.enums.Indices; 5 | import com.bitcoke.api.enums.Symbol; 6 | 7 | import java.util.Arrays; 8 | 9 | public class MarketRestApiExample { 10 | 11 | public static void main(String[] args) throws Exception { 12 | MarketRestApi marketRestApi = new MarketRestApi(); 13 | String result; 14 | 15 | System.out.println("refData"); 16 | result = marketRestApi.refData(); 17 | System.out.println(result); 18 | 19 | System.out.println("lastPrice"); 20 | result = marketRestApi.lastPrice(Arrays.asList( 21 | Symbol.XBTCUSD.toString(), 22 | Symbol.XETHUSD.toString(), 23 | Symbol.XEOSUSD.toString(), 24 | Symbol.XLTCUSD.toString(), 25 | Symbol.XBCHUSD.toString() 26 | )); 27 | System.out.println(result); 28 | 29 | System.out.println("price"); 30 | result = marketRestApi.price(Arrays.asList( 31 | Indices.BTCUSD.toString() 32 | )); 33 | System.out.println(result); 34 | 35 | System.out.println("depth"); 36 | result = marketRestApi.depth(Symbol.XBTCUSD.toString()); 37 | System.out.println(result); 38 | 39 | System.out.println("trades"); 40 | result = marketRestApi.trades(Symbol.XBTCUSD.toString()); 41 | System.out.println(result); 42 | 43 | System.out.println("quotes"); 44 | result = marketRestApi.quotes(Symbol.XBTCUSD.toString()); 45 | System.out.println(result); 46 | 47 | System.out.println("kLineByIndex"); 48 | result = marketRestApi.kLineByIndex(Symbol.XBTCUSD.toString(), 49 | "1M", 10, 0); 50 | System.out.println(result); 51 | 52 | System.out.println("kLineByTime"); 53 | result = marketRestApi.kLineByTime(Symbol.XBTCUSD.toString(), 54 | "1M", 10, null); 55 | System.out.println(result); 56 | 57 | System.out.println("kLineLatest"); 58 | result = marketRestApi.kLineLatest(Symbol.XBTCUSD.toString(), "1M"); 59 | System.out.println(result); 60 | 61 | System.out.println("kLineLatestPeriod"); 62 | Long timeSamp = System.currentTimeMillis() - 10 * 60 * 60 * 1000; 63 | result = marketRestApi.kLineLatestPeriod(Symbol.XBTCUSD.toString(), 64 | "1M", timeSamp); 65 | System.out.println(result); 66 | 67 | System.out.println("fundingRate"); 68 | result = marketRestApi.fundingRate(Arrays.asList( 69 | Symbol.XBTCUSD.toString(), 70 | Symbol.XETHUSD.toString(), 71 | Symbol.XEOSUSD.toString() 72 | )); 73 | System.out.println(result); 74 | 75 | System.out.println("tradeStatistics"); 76 | result = marketRestApi.tradeStatistics(Arrays.asList( 77 | Symbol.XBTCUSD.toString(), 78 | Symbol.XETHUSD.toString(), 79 | Symbol.XEOSUSD.toString() 80 | )); 81 | System.out.println(result); 82 | 83 | System.out.println("openInterest"); 84 | result = marketRestApi.openInterest(Indices.BTCUSD.toString()); 85 | System.out.println(result); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /api_java/src/test/java/com/bitcoke/api/examples/MarketWsExample.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.examples; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonParser; 6 | import org.java_websocket.client.WebSocketClient; 7 | import org.java_websocket.drafts.Draft_6455; 8 | import org.java_websocket.handshake.ServerHandshake; 9 | 10 | import java.net.URI; 11 | 12 | public class MarketWsExample { 13 | 14 | private static String WS_MARKET_URL = "wss://api.bitcoke.com/ws/market"; 15 | 16 | private static class MarketDataWebSocketClient extends WebSocketClient { 17 | 18 | private final String INDEX = "/api/index/price"; 19 | private final String DEPTH = "/api/depth/depth"; 20 | private final String FUNDINGRATE = "/api/kLine/fundingRate"; 21 | private final String OPENINTEREST = "/api/kLine/openInterest"; 22 | private final String TRADESTATISTICS = "/api/kLine/tradeStatistics"; 23 | private final String KLINE = "/api/kLine/kLine"; 24 | 25 | public MarketDataWebSocketClient(URI serverUri) { 26 | super(serverUri, new Draft_6455()); 27 | } 28 | 29 | @Override 30 | public void onOpen(ServerHandshake serverHandshake) { 31 | System.out.println("Connection opened"); 32 | // Index 33 | this.send("{\"op\":\"subscribe\", \"channel\":\"" + INDEX + "\", \"key\":\"BTCUSD\"}"); 34 | this.send("{\"op\":\"subscribe\", \"channel\":\"" + DEPTH + "\", \"key\":\"XBTCUSD\"}"); 35 | this.send("{\"op\":\"subscribe\", \"channel\":\"" + FUNDINGRATE + "\", \"key\":\"XBTCUSD\"}"); 36 | this.send("{\"op\":\"subscribe\", \"channel\":\"" + OPENINTEREST + "\", \"key\":\"BTCUSD\"}"); 37 | this.send("{\"op\":\"subscribe\", \"channel\":\"" + TRADESTATISTICS + "\", \"key\":\"BTCUSD\"}"); 38 | this.send("{\"op\":\"subscribe\", \"channel\":\"" + KLINE + "\", \"key\":\"XBTCUSD\", \"type\":\"1M\"}"); 39 | } 40 | 41 | @Override 42 | public void onMessage(String s) { 43 | JsonParser parser = new JsonParser(); 44 | JsonElement jsonElement = parser.parse(s); 45 | JsonObject jsonObject = jsonElement.getAsJsonObject(); 46 | String event = jsonObject.get("event").getAsString(); 47 | 48 | if (event.equalsIgnoreCase(INDEX)) { 49 | System.out.println(s); 50 | // do something 51 | } else if (event.equalsIgnoreCase(DEPTH)) { 52 | System.out.println(s); 53 | } else if (event.equalsIgnoreCase(FUNDINGRATE)) { 54 | System.out.println(s); 55 | } else if (event.equalsIgnoreCase(OPENINTEREST)) { 56 | System.out.println(s); 57 | } else if (event.equalsIgnoreCase(TRADESTATISTICS)) { 58 | System.out.println(s); 59 | } else if (event.equalsIgnoreCase(KLINE)) { 60 | System.out.println(s); 61 | } 62 | } 63 | 64 | @Override 65 | public void onClose(int i, String s, boolean b) { 66 | System.out.println("Connection is closed"); 67 | } 68 | 69 | @Override 70 | public void onError(Exception e) { 71 | System.out.println(e.getMessage()); 72 | } 73 | } 74 | 75 | public static void main(String[] args) throws Exception { 76 | WebSocketClient client = new MarketDataWebSocketClient(new URI(WS_MARKET_URL)); 77 | client.connect(); 78 | int i = 60; 79 | while (true) { 80 | try { 81 | Thread.sleep(1000); 82 | } catch (InterruptedException e) { 83 | e.printStackTrace(); 84 | } 85 | if (--i < 0) break; 86 | } 87 | client.close(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /api_java/src/test/java/com/bitcoke/api/examples/TradeRestApiExample.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.examples; 2 | 3 | import com.bitcoke.api.TradeRestApi; 4 | import com.bitcoke.api.enums.*; 5 | 6 | public class TradeRestApiExample { 7 | 8 | private static String apiKey = "your api key"; 9 | private static String apiSecret = "your api secret"; 10 | 11 | 12 | public static void main(String[] args) throws Exception { 13 | TradeRestApi tradeRestApi = new TradeRestApi(apiKey, apiSecret); 14 | 15 | String result; 16 | 17 | System.out.println("queryAccount"); 18 | result = tradeRestApi.queryAccount(); 19 | System.out.println(result); 20 | 21 | System.out.println("queryActiveOrders"); 22 | result = tradeRestApi.queryActiveOrders(Symbol.XBTCUSD.toString()); 23 | // result = tradeRestApi.queryActiveOrders(null); 24 | System.out.println(result); 25 | 26 | System.out.println("queryOrders"); 27 | result = tradeRestApi.queryOrders(null); 28 | // result = tradeRestApi.queryOrders("O101-20200904-035541-618-1495"); 29 | System.out.println(result); 30 | 31 | System.out.println("queryOrdersPro"); 32 | result = tradeRestApi.queryOrdersPro(null); 33 | // result = tradeRestApi.queryOrdersPro(System.currentTimeMillis()); 34 | System.out.println(result); 35 | 36 | System.out.println("queryOrderById"); 37 | result = tradeRestApi.queryOrderById("O101-20200904-035541-618-1495"); 38 | System.out.println(result); 39 | 40 | System.out.println("queryPosition"); 41 | result = tradeRestApi.queryPosition(); 42 | System.out.println(result); 43 | 44 | System.out.println("ledger"); 45 | result = tradeRestApi.ledger(Currency.BTC.toString(), "", 1L, 10L); 46 | System.out.println(result); 47 | 48 | // System.out.println("enterOrder"); 49 | //// result = tradeRestApi.enterOrder(Currency.BTC.toString(), Symbol.XBTCUSD.toString(), true, 50 | //// OrderSide.Buy.toString(), 20.0, OrderType.Market.toString(), null); 51 | // result = tradeRestApi.enterOrder(Currency.BTC.toString(), Symbol.XBTCUSD.toString(), true, 52 | // OrderSide.Buy.toString(), 20.0, OrderType.Limit.toString(), 9400.0); 53 | // System.out.println(result); 54 | 55 | System.out.println("amendOrder"); 56 | String orderId = "O101-20200904-081706-418-0885"; 57 | result = tradeRestApi.amendOrder(orderId, 9410.0, null, 58 | null, null, null, null); 59 | System.out.println(result); 60 | 61 | System.out.println("cancelOrder"); 62 | result = tradeRestApi.cancelOrder("O101-20200904-081650-026-0590"); 63 | System.out.println(result); 64 | 65 | System.out.println("closePosition"); 66 | result = tradeRestApi.closePosition(Currency.BTC.toString(), Symbol.XBTCUSD.toString(), 67 | PositionSide.Short.toString()); 68 | System.out.println(result); 69 | 70 | System.out.println("changePosLeverage"); 71 | result = tradeRestApi.changePosLeverage(Currency.EOS.toString(), Symbol.XBTCUSD.toString(), 20.0); 72 | System.out.println(result); 73 | 74 | System.out.println("riskSetting"); 75 | result = tradeRestApi.riskSetting(Currency.BTC.toString(), Symbol.XBTCUSD.toString(), 76 | PositionSide.Long.toString(), 0.0001, null, null, 77 | null, null); 78 | System.out.println(result); 79 | 80 | System.out.println("switchPosSide"); 81 | result = tradeRestApi.switchPosSide(Currency.EOS.toString(), true); 82 | System.out.println(result); 83 | 84 | System.out.println("switchToCross"); 85 | result = tradeRestApi.switchToCross(Currency.EOS.toString()); 86 | System.out.println(result); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /api_java/src/test/java/com/bitcoke/api/examples/TradeWsExample.java: -------------------------------------------------------------------------------- 1 | package com.bitcoke.api.examples; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonParser; 6 | import org.apache.commons.codec.digest.DigestUtils; 7 | import org.java_websocket.client.WebSocketClient; 8 | import org.java_websocket.drafts.Draft_6455; 9 | import org.java_websocket.handshake.ServerHandshake; 10 | 11 | import java.net.URI; 12 | 13 | public class TradeWsExample { 14 | 15 | private static String WS_TRADE_URL = "wss://api.bitcoke.com/ws/trade"; 16 | 17 | private static String apiKey = "your api key"; 18 | private static String apiSecret = "your api secret"; 19 | 20 | private static String loginUser = "your id"; 21 | private static String loginPwd = "your password"; 22 | 23 | private static String txId = "TX20200724-133934-511-458"; 24 | 25 | private static class TradingWebSocketClient extends WebSocketClient { 26 | 27 | private final String ACCOUNT_UPDATE = "/api/trade/accountUpdate"; 28 | private final String ORDER_UPDATE = "/api/trade/orderUpdate"; 29 | private final String POSITION_UPDATE = "/api/trade/positionUpdate"; 30 | private final String TRADELEDGER_UPDATE = "/api/trade/tradeLedgerUpdate"; 31 | private final String LOGIN = "login"; 32 | 33 | public TradingWebSocketClient(URI serverUri) { 34 | super(serverUri, new Draft_6455()); 35 | } 36 | 37 | @Override 38 | public void onOpen(ServerHandshake serverHandshake) { 39 | System.out.println("Connection opened"); 40 | login(txId, loginUser, loginPwd); 41 | } 42 | 43 | @Override 44 | public void onMessage(String s) { 45 | // System.out.println(s); 46 | JsonParser parser = new JsonParser(); 47 | JsonElement jsonElement = parser.parse(s); 48 | JsonObject jsonObject = jsonElement.getAsJsonObject(); 49 | String event = jsonObject.get("event").getAsString(); 50 | if (event.equalsIgnoreCase(LOGIN)) { 51 | String errCode = jsonObject.get("errCode").getAsString(); 52 | if (!errCode.equalsIgnoreCase("0")) { 53 | System.out.println("Login failed"); 54 | this.close(); 55 | return; 56 | } 57 | System.out.println("Login successfully"); 58 | // Subscribe accountUpdate 59 | String accountUpdateSub = getContent(ACCOUNT_UPDATE); 60 | System.out.println(accountUpdateSub); 61 | this.send(accountUpdateSub); 62 | // Subscribe orderUpdate 63 | accountUpdateSub = getContent(ORDER_UPDATE); 64 | System.out.println(accountUpdateSub); 65 | this.send(accountUpdateSub); 66 | // Subscribe positionUpdate 67 | accountUpdateSub = getContent(POSITION_UPDATE); 68 | System.out.println(accountUpdateSub); 69 | this.send(accountUpdateSub); 70 | // Subscribe tradeLedgerUpdate 71 | accountUpdateSub = getContent(TRADELEDGER_UPDATE); 72 | System.out.println(accountUpdateSub); 73 | this.send(accountUpdateSub); 74 | 75 | try { 76 | Thread.sleep(2 * 1000); 77 | } catch (InterruptedException e) { 78 | e.printStackTrace(); 79 | } 80 | 81 | } else if (event.equalsIgnoreCase(ACCOUNT_UPDATE)) { 82 | System.out.println(s); 83 | //do something 84 | } else if (event.equalsIgnoreCase(ORDER_UPDATE)) { 85 | System.out.println(s); 86 | } else if (event.equalsIgnoreCase(POSITION_UPDATE)) { 87 | System.out.println(s); 88 | } else if (event.equalsIgnoreCase(TRADELEDGER_UPDATE)) { 89 | System.out.println(s); 90 | } 91 | } 92 | 93 | @Override 94 | public void onClose(int i, String s, boolean b) { 95 | System.out.println("Connection is closed"); 96 | } 97 | 98 | @Override 99 | public void onError(Exception e) { 100 | System.out.println(e.getMessage()); 101 | } 102 | 103 | private void login(String txId, String user, String pwd) { 104 | String pass = DigestUtils.sha1Hex(pwd); 105 | this.send("{\"txId\":\"" + txId + "\",\"password\":\"" 106 | + pass + "\",\"user\":\"" + user + "\",\"op\":\"" + LOGIN + "\"}"); 107 | } 108 | 109 | private String getContent(String path) { 110 | long expires = System.currentTimeMillis() / 1000 + 5; 111 | String orginContent = "GET" + path + expires; 112 | String signature = DigestUtils.sha256Hex(apiSecret + orginContent); 113 | JsonObject object = new JsonObject(); 114 | object.addProperty("apiKey", apiKey); 115 | object.addProperty("signature", signature); 116 | object.addProperty("expires", expires); 117 | object.addProperty("op", "subscribe"); 118 | object.addProperty("channel", path); 119 | return object.toString(); 120 | } 121 | } 122 | 123 | public static void main(String[] args) throws Exception { 124 | TradingWebSocketClient client = new TradingWebSocketClient(new URI(WS_TRADE_URL)); 125 | client.connect(); 126 | int i = 60; 127 | while (true) { 128 | try { 129 | Thread.sleep(1000); 130 | } catch (InterruptedException e) { 131 | e.printStackTrace(); 132 | } 133 | if (--i < 0) break; 134 | } 135 | client.close(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /api_py/__pycache__/clientbase.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitCoke-Ex/open-api/68e0fcc44ed45b4d9fe30b76c428a7d9eda47acb/api_py/__pycache__/clientbase.cpython-38.pyc -------------------------------------------------------------------------------- /api_py/__pycache__/const.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitCoke-Ex/open-api/68e0fcc44ed45b4d9fe30b76c428a7d9eda47acb/api_py/__pycache__/const.cpython-38.pyc -------------------------------------------------------------------------------- /api_py/__pycache__/market_api.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitCoke-Ex/open-api/68e0fcc44ed45b4d9fe30b76c428a7d9eda47acb/api_py/__pycache__/market_api.cpython-38.pyc -------------------------------------------------------------------------------- /api_py/__pycache__/trading_api.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitCoke-Ex/open-api/68e0fcc44ed45b4d9fe30b76c428a7d9eda47acb/api_py/__pycache__/trading_api.cpython-38.pyc -------------------------------------------------------------------------------- /api_py/__pycache__/wallet_api.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitCoke-Ex/open-api/68e0fcc44ed45b4d9fe30b76c428a7d9eda47acb/api_py/__pycache__/wallet_api.cpython-38.pyc -------------------------------------------------------------------------------- /api_py/clientbase.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | import sys 4 | import requests 5 | import hashlib 6 | import time 7 | import urllib 8 | import const 9 | 10 | 11 | class ClientBase(object): 12 | def __init__(self, api_key, api_secret): 13 | super(ClientBase, self).__init__() 14 | self._api_key = api_key 15 | self._api_secret = api_secret 16 | 17 | def _get_params(self, data): 18 | if len(data) > 0: 19 | return '?' + urllib.parse.urlencode(data) 20 | else: 21 | return '' 22 | 23 | def _get_common_headers(self, requestMethod, path): 24 | expires = int(time.time()) + 1000 25 | signature = self._get_signature(requestMethod, path, expires) 26 | headers = { 27 | 'Content-Type': 'application/json;charset=UTF-8', 28 | 'apiKey': self._api_key, 29 | 'expires': str(expires), 30 | 'signature': signature 31 | } 32 | # print(headers) 33 | return headers 34 | 35 | def _get_signature(self, requestMethod, path, expires): 36 | if self._api_key == None or self._api_secret == None: 37 | return '' 38 | origin_text = self._api_secret + requestMethod + path + str(expires) 39 | signature = hashlib.sha256(origin_text.encode('utf-8')).hexdigest() 40 | return signature 41 | 42 | def _get(self, path, params): 43 | url = const.API_URL + path + self._get_params(params) 44 | # print(url) 45 | response = requests.get(url, headers=self._get_common_headers('GET', path)) 46 | return response 47 | 48 | def _post(self, path, params): 49 | url = const.API_URL + path + self._get_params(params) 50 | # print(url) 51 | response = requests.post(url, headers=self._get_common_headers('POST', path)) 52 | return response 53 | 54 | def _get_trade(self, path, params): 55 | url = const.TRADE_API_URL + path + self._get_params(params) 56 | # print(url) 57 | response = requests.get(url, headers=self._get_common_headers('GET', path)) 58 | return response 59 | 60 | def _post_trade(self, path, params): 61 | url = const.TRADE_API_URL + path + self._get_params(params) 62 | # print(url) 63 | response = requests.post(url, headers=self._get_common_headers('POST', path)) 64 | return response 65 | 66 | -------------------------------------------------------------------------------- /api_py/const.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | API_URL = 'http://api.bitcoke.com/' 4 | TRADE_API_URL = 'http://api.bitcoke.com/trade/' 5 | 6 | 7 | #Instrument 8 | SYMBOL_XBTCUSD = 'XBTCUSD' 9 | SYMBOL_XETHUSD = 'XETHUSD' 10 | SYMBOL_XEOSWUSD = 'XEOSUSD' 11 | SYMBOL_XLTCUSD = 'XLTCUSD' 12 | SYMBOL_XBCHUSD = 'XBCHUSD' 13 | 14 | #Index 15 | SYMBOL_BTCUSD = 'BTCUSD' 16 | SYMBOL_ETHUSD = 'ETHUSD' 17 | SYMBOL_EOSWUSD = 'EOSUSD' 18 | SYMBOL_LTCUSD = 'LTCUSD' 19 | SYMBOL_BCHUSD = 'BCHUSD' 20 | 21 | #currency 22 | CURRENCY_BTC = 'BTC' 23 | CURRENCY_EOS = 'EOS' 24 | CURRENCY_ETH = 'ETH' 25 | CURRENCY_USDT = 'USDT' 26 | 27 | #Type of order price 28 | ORDER_TYPE_LIMIT = 'Limit' 29 | ORDER_TYPE_MARKET = 'Market' 30 | 31 | #Order side 32 | SIDE_BUY = 'Buy' 33 | SIDE_SELL = 'Sell' 34 | 35 | #Type of advanced order 36 | TIF_GOOD_TILL_CANCEL = 'GOOD_TILL_CANCEL' 37 | TIF_IMMEDIATE_OR_CANCEL = 'IMMEDIATE_OR_CANCEL' 38 | TIF_FILL_OR_KILL = 'FILL_OR_KILL' 39 | TIF_QUEUE_OR_CANCEL = 'QUEUE_OR_CANCEL' 40 | 41 | #Trigger type of price for conditional order 42 | TIGGER_TYPE_LAST = "LAST" 43 | TIGGER_TYPE_INDEX = "INDEX" 44 | 45 | #Position side 46 | SIDE_LONG = 'Long' 47 | SIDE_SHORT = 'Short' 48 | 49 | #K line Type 50 | K_LINE_TYPE_1M = '1M' 51 | K_LINE_TYPE_3M = '3M' 52 | K_LINE_TYPE_5M = '5M' 53 | K_LINE_TYPE_10M = '10M' 54 | K_LINE_TYPE_15M = '15M' 55 | K_LINE_TYPE_30M = '30M' 56 | K_LINE_TYPE_1H = '1H' 57 | K_LINE_TYPE_2H = '2H' 58 | K_LINE_TYPE_4H = '4H' 59 | K_LINE_TYPE_6H = '6H' 60 | K_LINE_TYPE_8H = '8H' 61 | K_LINE_TYPE_12H = '12H' 62 | K_LINE_TYPE_D = 'D' 63 | K_LINE_TYPE_W = 'W' 64 | K_LINE_TYPE_MTH = 'MTH' 65 | 66 | 67 | -------------------------------------------------------------------------------- /api_py/example.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | import time 4 | from trading_api import TradingApi 5 | from wallet_api import WalletApi 6 | from market_api import MarketApi 7 | import const 8 | 9 | #这里请填写自己申请的api key和secret 10 | #申请流程可以参考以下文档 11 | #https://www.bitcoke.com/api-doc/zh/rest.html#%E7%94%B3%E8%AF%B7-api-key 12 | api_key = '***your api key***' 13 | api_secret = '***your api secret***' 14 | 15 | ## Trading Api Example 16 | # 交易只读 API 17 | 18 | tradingApi = TradingApi(api_key, api_secret) 19 | 20 | ## get 21 | 22 | #查询用户的交易账号信息。(60次/分/Key) 23 | # response = tradingApi.queryAccounts() 24 | 25 | #查询用户尚未完成的订单列表(包括委托单和条件单)。(60次/分/Key) 26 | # response = tradingApi.queryActiveOrders() 27 | # response = tradingApi.queryActiveOrders(const.SYMBOL_XBTCUSD) 28 | 29 | #查询用户订单历史,订单按时间倒叙排列。(30次/分/Key) 30 | # response = tradingApi.queryOrders() 31 | # response = tradingApi.queryOrders("O101-20200708-092521-611-1647") 32 | 33 | #根据订单 Id 查询订单。(5次/秒/Key) 34 | # response = tradingApi.queryOrderById("O101-20200708-092521-611-1647") 35 | 36 | #查询用户的当前持仓。(60次/分/Key) 37 | # response = tradingApi.queryPosition() 38 | 39 | #按币种分页查询用户交易账号的账本记录。(10次/分/Key) 40 | # response = tradingApi.ledger(const.CURRENCY_EOS, '', 1, 10) 41 | 42 | 43 | ## post 44 | # 交易 API 45 | 46 | #下单接口。(10次/秒/Key) 47 | # orderData = { 48 | # "currency" : const.CURRENCY_EOS, 49 | # "openPosition" : True, 50 | # "orderType" : const.ORDER_TYPE_MARKET, 51 | # "qty" : 20, 52 | # "side" : const.SIDE_BUY, 53 | # "symbol" : const.SYMBOL_XBTCUSD, 54 | # } 55 | # response = tradingApi.enterOrder(orderData) 56 | 57 | # orderData = { 58 | # "currency" : const.CURRENCY_EOS, 59 | # "openPosition" : True, 60 | # "orderType" : const.ORDER_TYPE_LIMIT, 61 | # "price" : 9200, 62 | # "qty" : 20, 63 | # "side" : const.SIDE_BUY, 64 | # "symbol" : const.SYMBOL_XBTCUSD, 65 | # } 66 | # response = tradingApi.enterOrder(orderData) 67 | 68 | #根据订单Id进行撤单。(20次/秒/Key) 69 | # response = tradingApi.cancelOrder("O101-20200708-082736-885-0361") 70 | 71 | #修改订单信息。(5次/秒/Key) 72 | # orderData = { 73 | # "orderId" : "O101-20200709-025019-115-0954", 74 | # "price" : 9201, 75 | # } 76 | # response = tradingApi.amendOrder(orderData) 77 | 78 | #市价全部平仓。(4次/秒/Key) 79 | # response = tradingApi.closePosition(const.CURRENCY_EOS, const.SYMBOL_XBTCUSD, const.SIDE_LONG) 80 | 81 | #修改仓位杠杆设定。(4次/秒/Key) 82 | # response = tradingApi.changePosLeverage(const.CURRENCY_EOS, const.SYMBOL_XBTCUSD, 20) 83 | 84 | #修改仓位风控设定。(5次/秒/Key) 85 | # settingData = { 86 | # "currency" : const.CURRENCY_EOS, 87 | # "side" : const.SIDE_LONG, 88 | # "symbol" : const.SYMBOL_XBTCUSD, 89 | # "addDeposit" : 0.001, 90 | # } 91 | # response = tradingApi.riskSetting(settingData) 92 | 93 | #切换账号单双向持仓模式。(4次/秒/Key) 94 | # response = tradingApi.switchPosSide(const.CURRENCY_EOS, True) 95 | 96 | #将账号从逐仓模式切换为全仓模式。(4次/秒/Key) 97 | # response = tradingApi.switchToCross(const.CURRENCY_EOS) 98 | 99 | 100 | ## Wallet Api Example 101 | 102 | walletApi = WalletApi(api_key, api_secret) 103 | 104 | #获取用户钱包列表。 105 | # response = walletApi.list() 106 | 107 | #获取用户充币地址。 108 | # response = walletApi.depositAddress() 109 | 110 | #获取用户钱包账簿。 111 | # response = walletApi.ledger() 112 | 113 | 114 | ## Market Api Example 115 | #行情及报价接口可直接使用,不需要申请 API KEY;请求频率根据发出请求服务器的 IP 限制。 116 | 117 | marketApi = MarketApi() 118 | 119 | #获取合约信息。(1次/秒/IP) 120 | # response = marketApi.refData() 121 | 122 | #获取合约最新成交价。(1次/秒/IP) 123 | # response = marketApi.lastPrice() 124 | # response = marketApi.lastPrice(const.SYMBOL_XBTCUSD, const.SYMBOL_XETHUSD) 125 | 126 | #获取标记价。(5次/秒/IP) 127 | # response = marketApi.price() 128 | # response = marketApi.price(const.SYMBOL_BTCUSD, const.SYMBOL_ETHUSD) 129 | 130 | #获取市场深度。(5次/秒/IP) 131 | # response = marketApi.depth(const.SYMBOL_XBTCUSD) 132 | 133 | #获取最新成交记录。(5次/秒/IP) 134 | # response = marketApi.trades(const.SYMBOL_XBTCUSD) 135 | 136 | #获取市场深度和最近成交记录。(5次/秒/IP) 137 | # response = marketApi.quotes(const.SYMBOL_XBTCUSD) 138 | # response = marketApi.quotes(const.SYMBOL_XBTCUSD, ['1594621313287000012', '1594621313287000015']) 139 | 140 | #获取历史 K 线以及成交统计相关数据。(15次/分/IP) 141 | # response = marketApi.kLine_byIndex(const.SYMBOL_XBTCUSD, const.K_LINE_TYPE_1M, 10, 0) 142 | 143 | #通过时间索引获取历史 K 线。(15次/分/IP) 144 | # response = marketApi.kLine_byTime(const.SYMBOL_XBTCUSD, const.K_LINE_TYPE_1M, 10) 145 | 146 | #获取最新一根 K 线数据。(75次/分/IP) 147 | # response = marketApi.kLine_latest(const.SYMBOL_XBTCUSD, const.K_LINE_TYPE_1M) 148 | 149 | #获取上次拉取 K 线后的更新数据。(75次/分/IP) 150 | # response = marketApi.kLine_latestPeriod(const.SYMBOL_XBTCUSD, const.K_LINE_TYPE_1M, int(time.time())) 151 | 152 | #获取资金费率。(5次/秒/IP) 153 | # response = marketApi.kLine_fundingRate(const.SYMBOL_XBTCUSD, const.SYMBOL_XETHUSD) 154 | 155 | #获取最近24小时的成交统计数据。(5次/秒/IP) 156 | # response = marketApi.kLine_tradeStatistics(const.SYMBOL_XBTCUSD, const.SYMBOL_XETHUSD) 157 | 158 | #获取系统合约持仓量。(5次/秒/IP) 159 | # response = marketApi.kLine_openInterest(const.SYMBOL_BTCUSD) 160 | 161 | 162 | if response.status_code == 200: 163 | response_data = json.loads(response.text) 164 | print(response_data) 165 | # result = (json.dumps(response_data['result']) if response_data['code'] == 0 else response_data['message']) 166 | # print(result) 167 | else: 168 | print(response.text) 169 | 170 | -------------------------------------------------------------------------------- /api_py/market_api.py: -------------------------------------------------------------------------------- 1 | 2 | from clientbase import ClientBase 3 | 4 | class MarketApi(ClientBase): 5 | def __init__(self): 6 | super(MarketApi, self).__init__(None, None) 7 | 8 | def refData(self): 9 | params = {} 10 | respone = self._get("/api/basic/refData", params) 11 | return respone 12 | 13 | def lastPrice(self, *symbols): 14 | params = { "symbols" : ','.join(symbols) } if len(symbols) > 0 else {} 15 | respone = self._get("/api/basic/lastPrice", params) 16 | return respone 17 | 18 | def price(self, *symbols): 19 | params = { "symbols" : ','.join(symbols) } if len(symbols) > 0 else {} 20 | respone = self._get("/api/index/price", params) 21 | return respone 22 | 23 | def depth(self, symbol): 24 | params = { "symbol" : symbol } 25 | respone = self._get("/api/depth/depth", params) 26 | return respone 27 | 28 | def trades(self, symbol): 29 | params = { "symbol" : symbol } 30 | respone = self._get("/api/depth/trades", params) 31 | return respone 32 | 33 | def quotes(self, symbol, sequence=''): 34 | params = { 35 | "symbol" : symbol, 36 | "sequence" : sequence, 37 | } 38 | respone = self._get("/api/depth/quotes", params) 39 | return respone 40 | 41 | def kLine_byIndex(self, symbol, sType, step, iFrom=0): 42 | params = { 43 | "from" : iFrom, 44 | "step" : step, 45 | "symbol" : symbol, 46 | "type" : sType, 47 | } 48 | respone = self._get("/api/kLine/byIndex", params) 49 | return respone 50 | 51 | def kLine_byTime(self, symbol, sType, step, iFrom=''): 52 | params = { 53 | "from" : iFrom, 54 | "step" : step, 55 | "symbol" : symbol, 56 | "type" : sType, 57 | } 58 | respone = self._get("/api/kLine/byTime", params) 59 | return respone 60 | 61 | def kLine_latest(self, symbol, sType): 62 | params = { 63 | "symbol" : symbol, 64 | "type" : sType, 65 | } 66 | respone = self._get("/api/kLine/latest", params) 67 | return respone 68 | 69 | def kLine_latestPeriod(self, symbol, sType, lastKTime=''): 70 | params = { 71 | "symbol" : symbol, 72 | "type" : sType, 73 | "lastKTime" : lastKTime, 74 | } 75 | respone = self._get("/api/kLine/latestPeriod", params) 76 | return respone 77 | 78 | def kLine_fundingRate(self, *symbols): 79 | params = { "symbols" : ','.join(symbols) } if len(symbols) > 0 else {} 80 | respone = self._get("/api/kLine/fundingRate", params) 81 | return respone 82 | 83 | def kLine_tradeStatistics(self, *symbols): 84 | params = { "symbols" : ','.join(symbols) } if len(symbols) > 0 else {} 85 | respone = self._get("/api/kLine/tradeStatistics", params) 86 | return respone 87 | 88 | def kLine_openInterest(self, symbol): 89 | params = { "symbol" : symbol } 90 | respone = self._get("/api/kLine/openInterest", params) 91 | return respone 92 | -------------------------------------------------------------------------------- /api_py/readme.md: -------------------------------------------------------------------------------- 1 | ### Tools 2 | Python version:3.6+ (3.8 recommended) 3 | 4 | Installation required Library 5 | ``` 6 | pip install requests 7 | pip install websockets 8 | ``` 9 | 10 | 11 | ### Api Demo 12 | 13 | * #### RestApi 14 | Running ```example.py``` 15 | and uncomment the corresponding method to see the result of the call. 16 | 17 | * #### WebSocketApi 18 | Running ```websocket_example.py``` 19 | according to the trade / market, select the corresponding startup method, uncomment to view the call result 20 | 21 | ### Document 22 | https://www.bitcoke.com/api-doc/ 23 | -------------------------------------------------------------------------------- /api_py/trading_api.py: -------------------------------------------------------------------------------- 1 | 2 | from clientbase import ClientBase 3 | 4 | 5 | class TradingApi(ClientBase): 6 | def __init__(self, api_key, api_secret): 7 | super(TradingApi, self).__init__(api_key, api_secret) 8 | 9 | def queryAccounts(self): 10 | params = {} 11 | respone = self._get_trade("/api/trade/queryAccounts", params) 12 | return respone 13 | 14 | def queryActiveOrders(self, symbol=''): 15 | params = {"symbol" : symbol} 16 | respone = self._get_trade("/api/trade/queryActiveOrders", params) 17 | return respone 18 | 19 | def queryOrders(self, prevId=''): 20 | params = {"prevId" : prevId} 21 | respone = self._get_trade("/api/trade/queryOrders", params) 22 | return respone 23 | 24 | def queryOrderById(self, orderId): 25 | params = {"orderId" : orderId} 26 | respone = self._get_trade("/api/trade/queryOrderById", params) 27 | return respone 28 | 29 | def queryPosition(self): 30 | params = {} 31 | respone = self._get_trade("/api/trade/queryPosition", params) 32 | return respone 33 | 34 | def ledger(self, currency, fromId, pageNo, pageSize): 35 | params = { 36 | "currency" : currency, 37 | "from" : fromId, 38 | "pageNo" : pageNo, 39 | "pageSize" : pageSize, 40 | } 41 | respone = self._get_trade("/api/trade/ledger", params) 42 | return respone 43 | 44 | 45 | def enterOrder(self, data): 46 | params = { 47 | "currency" : data.get("currency"), 48 | "symbol" : data.get("symbol"), 49 | "openPosition" : data.get("openPosition"), 50 | "side" : data.get("side"), 51 | "qty" : data.get("qty"), 52 | "orderType" : data.get("orderType"), 53 | "price" : data.get("price") or '', 54 | "hidden" : data.get("hidden") or False, 55 | "showQty" : data.get("showQty") or '', 56 | "stopLossPrice" : data.get("stopLossPrice") or '', 57 | "stopWinPrice" : data.get("stopWinPrice") or '', 58 | "stopWinType" : data.get("stopWinType") or '', 59 | "tif" : data.get("tif") or '', 60 | "trailingStop" : data.get("trailingStop") or '', 61 | "triggerPrice" : data.get("triggerPrice") or '', 62 | "triggerType" : data.get("triggerType") or '', 63 | } 64 | respone = self._post_trade("/api/trade/enterOrder", params) 65 | return respone 66 | 67 | def cancelOrder(self, orderId): 68 | params = { "orderId" : orderId } 69 | respone = self._post_trade("/api/trade/cancelOrder", params) 70 | return respone 71 | 72 | def amendOrder(self, data): 73 | params = { 74 | "orderId" : data.get("orderId"), 75 | "price" : data.get("price") or '', 76 | "qty" : data.get("qty") or '', 77 | "stopLossPrice" : data.get("stopLossPrice") or '', 78 | "stopWinPrice" : data.get("stopWinPrice") or '', 79 | "trailingStop" : data.get("trailingStop") or '', 80 | "triggerPrice" : data.get("triggerPrice") or '', 81 | } 82 | respone = self._post_trade("/api/trade/amendOrder", params) 83 | return respone 84 | 85 | def closePosition(self, currency, symbol, side): 86 | params = { 87 | "currency" : currency, 88 | "symbol" : symbol, 89 | "side" : side, 90 | } 91 | respone = self._post_trade("/api/trade/closePosition", params) 92 | return respone 93 | 94 | def changePosLeverage(self, currency, symbol, leverage): 95 | params = { 96 | "currency" : currency, 97 | "symbol" : symbol, 98 | "leverage" : leverage, 99 | } 100 | respone = self._post_trade("/api/trade/changePosLeverage", params) 101 | return respone 102 | 103 | def riskSetting(self, data): 104 | params = { 105 | "currency" : data.get("currency"), 106 | "side" : data.get("side"), 107 | "symbol" : data.get("symbol"), 108 | "addDeposit" : data.get("addDeposit") or '', 109 | "stopLossPrice" : data.get("stopLossPrice") or '', 110 | "stopWinPrice" : data.get("stopWinPrice") or '', 111 | "stopWinType" : data.get("stopWinType") or '', 112 | "trailingStop" : data.get("trailingStop") or '', 113 | } 114 | respone = self._post_trade("/api/trade/riskSetting", params) 115 | return respone 116 | 117 | def switchPosSide(self, currency, twoSidePosition): 118 | params = { 119 | "currency" : currency, 120 | "twoSidePosition" : twoSidePosition, 121 | } 122 | respone = self._post_trade("/api/trade/switchPosSide", params) 123 | return respone 124 | 125 | def switchToCross(self, currency): 126 | params = { "currency" : currency } 127 | respone = self._post_trade("/api/trade/switchToCross", params) 128 | return respone 129 | 130 | -------------------------------------------------------------------------------- /api_py/wallet_api.py: -------------------------------------------------------------------------------- 1 | 2 | from clientbase import ClientBase 3 | 4 | 5 | class WalletApi(ClientBase): 6 | def __init__(self, api_key, api_secret): 7 | super(WalletApi, self).__init__(api_key, api_secret) 8 | 9 | def list(self): 10 | params = {} 11 | respone = self._get_trade("/api/wallet/list", params) 12 | return respone 13 | 14 | def depositAddress(self): 15 | params = {} 16 | respone = self._get_trade("/api/wallet/depositAddress", params) 17 | return respone 18 | 19 | def ledger(self): 20 | params = {} 21 | respone = self._get_trade("/api/wallet/ledger", params) 22 | return respone 23 | 24 | -------------------------------------------------------------------------------- /api_py/websocket_example.py: -------------------------------------------------------------------------------- 1 | 2 | import websockets 3 | import asyncio 4 | import time 5 | import json 6 | import hashlib 7 | 8 | 9 | def get_signature(api_secret, requestMethod, path, expires): 10 | origin_text = api_secret + requestMethod + path + str(expires) 11 | signature = hashlib.sha256(origin_text.encode('utf-8')).hexdigest() 12 | return signature 13 | 14 | def login_str(uid, password, txId): 15 | pwdsha = hashlib.sha1(password.encode('utf-8')).hexdigest() 16 | param = {"op":"login", "user":uid, "password":pwdsha, "txId":txId} 17 | return json.dumps(param) 18 | 19 | def heartbeat_str(uid, txId): 20 | param = {"op":"heartbeat", "user":uid, "txId":txId} 21 | return json.dumps(param) 22 | 23 | def subscript_str(api_key, api_secret, channel): 24 | expires = int(time.time()) + 10 25 | param = { 26 | "apiKey": api_key, 27 | "signature": get_signature(api_secret, 'GET', channel, expires), 28 | "expires": expires, 29 | "op": "subscribe", 30 | "channel": channel, 31 | } 32 | return json.dumps(param) 33 | 34 | def unsubscript_str(api_key, channel): 35 | param = { 36 | "apiKey": api_key, 37 | "op": "unsubscribe", 38 | "channel": channel, 39 | } 40 | return json.dumps(param) 41 | 42 | async def subscribe_trade(url, api_key, api_secret, uid, password, txId): 43 | while True: 44 | try: 45 | async with websockets.connect(url) as ws: 46 | rec = await ws.recv() 47 | print("connect:", rec) 48 | 49 | #login 50 | loginStr = login_str(uid, password, txId) 51 | await ws.send(loginStr) 52 | rec = await ws.recv() 53 | print(rec) 54 | loginResult = json.loads(rec) 55 | if loginResult.get("errCode") != 0: 56 | print("Login fail") 57 | break 58 | 59 | #subscript examples 60 | #订阅接收账号的动态更新 61 | sub_str = subscript_str(api_key, api_secret, "/api/trade/accountUpdate") 62 | await ws.send(sub_str) 63 | 64 | #订阅订单数据更新 65 | sub_str = subscript_str(api_key, api_secret, "/api/trade/orderUpdate") 66 | await ws.send(sub_str) 67 | 68 | #订阅仓位数据更新 69 | sub_str = subscript_str(api_key, api_secret, "/api/trade/positionUpdate") 70 | await ws.send(sub_str) 71 | 72 | #订阅合约账号出入金数据更新 73 | sub_str = subscript_str(api_key, api_secret, "/api/trade/tradeLedgerUpdate") 74 | await ws.send(sub_str) 75 | 76 | while True: 77 | try: 78 | rec = await asyncio.wait_for(ws.recv(), timeout=30) 79 | except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed) as e: 80 | try: 81 | heartbeatStr = heartbeat_str(uid, txId) 82 | await ws.send(heartbeatStr) 83 | rec = await ws.recv() 84 | print(rec) 85 | continue 86 | except Exception as e: 87 | print(e) 88 | break 89 | print(rec) 90 | 91 | except Exception as e: 92 | print(e) 93 | print("Try reconnect...") 94 | continue 95 | 96 | def subscript_str_without_login(channel, **kwargs): 97 | param = { 98 | "op": "subscribe", 99 | "channel": channel, 100 | } 101 | param.update(kwargs) 102 | return json.dumps(param) 103 | 104 | def unsubscript_str_without_login(channel): 105 | param = { 106 | "op": "unsubscribe", 107 | "channel": channel, 108 | } 109 | return json.dumps(param) 110 | 111 | async def subscribe_market(url): 112 | while True: 113 | try: 114 | async with websockets.connect(url) as ws: 115 | rec = await ws.recv() 116 | print("connect:", rec) 117 | 118 | #subscript examples 119 | #标记价 120 | # sub_str = subscript_str_without_login("/api/index/price", key="BTCUSD") 121 | # await ws.send(sub_str) 122 | 123 | #深度 124 | # sub_str = subscript_str_without_login("/api/depth/depth", key="XBTCUSD") 125 | # await ws.send(sub_str) 126 | 127 | #资金费率 128 | # sub_str = subscript_str_without_login("/api/kLine/fundingRate", key="XBTCUSD") 129 | # await ws.send(sub_str) 130 | 131 | #持仓量 132 | # sub_str = subscript_str_without_login("/api/kLine/openInterest", key="BTCUSD") 133 | # await ws.send(sub_str) 134 | 135 | #24小时成交统计 136 | # sub_str = subscript_str_without_login("/api/kLine/tradeStatistics", key="BTCUSD") 137 | # await ws.send(sub_str) 138 | 139 | #K线更新 140 | sub_str = subscript_str_without_login("/api/kLine/kLine", key="XBTCUSD", type="1M") 141 | await ws.send(sub_str) 142 | 143 | while True: 144 | rec = await ws.recv() 145 | print(rec) 146 | 147 | except Exception as e: 148 | print(e) 149 | time.sleep(1) 150 | print("Try reconnect...") 151 | continue 152 | 153 | 154 | 155 | 156 | url_trade = 'wss://api.bitcoke.com/ws/trade' 157 | url_market = 'wss://api.bitcoke.com/ws/market' 158 | 159 | #这里填写自己申请的api key和secret,申请流程参考以下文档 160 | #https://www.bitcoke.com/api-doc/zh/#%E7%94%B3%E8%AF%B7-api-key 161 | api_key = '***your api key***' 162 | api_secret = '***your api secret***' 163 | 164 | #这里填写自己的uid和密码 165 | uid = 'your id' 166 | password = 'your password' 167 | txId = uid + "_" + str(int(time.time())) 168 | 169 | loop = asyncio.get_event_loop() 170 | 171 | #个人交易数据,需要登录,需要api key和secret 172 | # loop.run_until_complete(subscribe_trade(url_trade, api_key, api_secret, uid, password, txId)) 173 | 174 | #行情数据,不需要登录 175 | loop.run_until_complete(subscribe_market(url_market)) 176 | 177 | loop.close() 178 | 179 | --------------------------------------------------------------------------------