├── 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 |
--------------------------------------------------------------------------------