ccxt-look 1.81.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
package/js/lbank.js ADDED
@@ -0,0 +1,760 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, DDoSProtection, AuthenticationError, InvalidOrder, ArgumentsRequired } = require ('./base/errors');
7
+ const Precise = require ('./base/Precise');
8
+
9
+ // ---------------------------------------------------------------------------
10
+
11
+ module.exports = class lbank extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'lbank',
15
+ 'name': 'LBank',
16
+ 'countries': [ 'CN' ],
17
+ 'version': 'v1',
18
+ 'has': {
19
+ 'CORS': undefined,
20
+ 'spot': true,
21
+ 'margin': false,
22
+ 'swap': false,
23
+ 'future': false,
24
+ 'option': false,
25
+ 'addMargin': false,
26
+ 'cancelOrder': true,
27
+ 'createOrder': true,
28
+ 'createReduceOnlyOrder': false,
29
+ 'fetchBalance': true,
30
+ 'fetchBorrowRate': false,
31
+ 'fetchBorrowRateHistories': false,
32
+ 'fetchBorrowRateHistory': false,
33
+ 'fetchBorrowRates': false,
34
+ 'fetchBorrowRatesPerSymbol': false,
35
+ 'fetchClosedOrders': true,
36
+ 'fetchFundingHistory': false,
37
+ 'fetchFundingRate': false,
38
+ 'fetchFundingRateHistory': false,
39
+ 'fetchFundingRates': false,
40
+ 'fetchIndexOHLCV': false,
41
+ 'fetchLeverage': false,
42
+ 'fetchLeverageTiers': false,
43
+ 'fetchMarkets': true,
44
+ 'fetchMarkOHLCV': false,
45
+ 'fetchOHLCV': true,
46
+ 'fetchOpenOrders': undefined, // status 0 API doesn't work
47
+ 'fetchOrder': true,
48
+ 'fetchOrderBook': true,
49
+ 'fetchOrders': true,
50
+ 'fetchPosition': false,
51
+ 'fetchPositions': false,
52
+ 'fetchPositionsRisk': false,
53
+ 'fetchPremiumIndexOHLCV': false,
54
+ 'fetchTicker': true,
55
+ 'fetchTickers': true,
56
+ 'fetchTrades': true,
57
+ 'fetchTradingFee': false,
58
+ 'fetchTradingFees': false,
59
+ 'reduceMargin': false,
60
+ 'setLeverage': false,
61
+ 'setMarginMode': false,
62
+ 'setPositionMode': false,
63
+ 'withdraw': true,
64
+ },
65
+ 'timeframes': {
66
+ '1m': 'minute1',
67
+ '5m': 'minute5',
68
+ '15m': 'minute15',
69
+ '30m': 'minute30',
70
+ '1h': 'hour1',
71
+ '2h': 'hour2',
72
+ '4h': 'hour4',
73
+ '6h': 'hour6',
74
+ '8h': 'hour8',
75
+ '12h': 'hour12',
76
+ '1d': 'day1',
77
+ '1w': 'week1',
78
+ },
79
+ 'urls': {
80
+ 'logo': 'https://user-images.githubusercontent.com/1294454/38063602-9605e28a-3302-11e8-81be-64b1e53c4cfb.jpg',
81
+ 'api': 'https://api.lbank.info',
82
+ 'www': 'https://www.lbank.info',
83
+ 'doc': 'https://github.com/LBank-exchange/lbank-official-api-docs',
84
+ 'fees': 'https://www.lbank.info/fees.html',
85
+ 'referral': 'https://www.lbex.io/invite?icode=7QCY',
86
+ },
87
+ 'api': {
88
+ 'public': {
89
+ 'get': [
90
+ 'currencyPairs',
91
+ 'ticker',
92
+ 'depth',
93
+ 'trades',
94
+ 'kline',
95
+ 'accuracy',
96
+ ],
97
+ },
98
+ 'private': {
99
+ 'post': [
100
+ 'user_info',
101
+ 'create_order',
102
+ 'cancel_order',
103
+ 'orders_info',
104
+ 'orders_info_history',
105
+ 'withdraw',
106
+ 'withdrawCancel',
107
+ 'withdraws',
108
+ 'withdrawConfigs',
109
+ ],
110
+ },
111
+ },
112
+ 'fees': {
113
+ 'trading': {
114
+ 'maker': this.parseNumber ('0.001'),
115
+ 'taker': this.parseNumber ('0.001'),
116
+ },
117
+ 'funding': {
118
+ 'withdraw': {},
119
+ },
120
+ },
121
+ 'commonCurrencies': {
122
+ 'GMT': 'GMT Token',
123
+ 'PNT': 'Penta',
124
+ 'VET_ERC20': 'VEN',
125
+ },
126
+ 'options': {
127
+ 'cacheSecretAsPem': true,
128
+ },
129
+ });
130
+ }
131
+
132
+ async fetchMarkets (params = {}) {
133
+ const response = await this.publicGetAccuracy (params);
134
+ //
135
+ // [
136
+ // {
137
+ // "symbol": "btc_usdt",
138
+ // "quantityAccuracy": "4",
139
+ // "minTranQua": "0.0001",
140
+ // "priceAccuracy": "2"
141
+ // },
142
+ // ...
143
+ // ]
144
+ //
145
+ const result = [];
146
+ for (let i = 0; i < response.length; i++) {
147
+ const market = response[i];
148
+ const id = market['symbol'];
149
+ const parts = id.split ('_');
150
+ let baseId = undefined;
151
+ let quoteId = undefined;
152
+ const numParts = parts.length;
153
+ // lbank will return symbols like "vet_erc20_usdt"
154
+ if (numParts > 2) {
155
+ baseId = parts[0] + '_' + parts[1];
156
+ quoteId = parts[2];
157
+ } else {
158
+ baseId = parts[0];
159
+ quoteId = parts[1];
160
+ }
161
+ const base = this.safeCurrencyCode (baseId);
162
+ const quote = this.safeCurrencyCode (quoteId);
163
+ result.push ({
164
+ 'id': id,
165
+ 'symbol': base + '/' + quote,
166
+ 'base': base,
167
+ 'quote': quote,
168
+ 'settle': undefined,
169
+ 'baseId': baseId,
170
+ 'quoteId': quoteId,
171
+ 'settleId': undefined,
172
+ 'type': 'spot',
173
+ 'spot': true,
174
+ 'margin': false,
175
+ 'swap': false,
176
+ 'future': false,
177
+ 'option': false,
178
+ 'active': true,
179
+ 'contract': false,
180
+ 'linear': undefined,
181
+ 'inverse': undefined,
182
+ 'contractSize': undefined,
183
+ 'expiry': undefined,
184
+ 'expiryDatetime': undefined,
185
+ 'strike': undefined,
186
+ 'optionType': undefined,
187
+ 'precision': {
188
+ 'amount': this.safeInteger (market, 'quantityAccuracy'),
189
+ 'price': this.safeInteger (market, 'priceAccuracy'),
190
+ },
191
+ 'limits': {
192
+ 'leverage': {
193
+ 'min': undefined,
194
+ 'max': undefined,
195
+ },
196
+ 'amount': {
197
+ 'min': this.safeFloat (market, 'minTranQua'),
198
+ 'max': undefined,
199
+ },
200
+ 'price': {
201
+ 'min': undefined,
202
+ 'max': undefined,
203
+ },
204
+ 'cost': {
205
+ 'min': undefined,
206
+ 'max': undefined,
207
+ },
208
+ },
209
+ 'info': id,
210
+ });
211
+ }
212
+ return result;
213
+ }
214
+
215
+ parseTicker (ticker, market = undefined) {
216
+ //
217
+ // {
218
+ // "symbol":"btc_usdt",
219
+ // "ticker":{
220
+ // "high":43416.06,
221
+ // "vol":7031.7427,
222
+ // "low":41804.26,
223
+ // "change":1.33,
224
+ // "turnover":300302447.81,
225
+ // "latest":43220.4
226
+ // },
227
+ // "timestamp":1642201617747
228
+ // }
229
+ //
230
+ const marketId = this.safeString (ticker, 'symbol');
231
+ market = this.safeMarket (marketId, market, '_');
232
+ const symbol = market['symbol'];
233
+ const timestamp = this.safeInteger (ticker, 'timestamp');
234
+ const info = ticker;
235
+ ticker = info['ticker'];
236
+ const last = this.safeString (ticker, 'latest');
237
+ const percentage = this.safeString (ticker, 'change');
238
+ return this.safeTicker ({
239
+ 'symbol': symbol,
240
+ 'timestamp': timestamp,
241
+ 'datetime': this.iso8601 (timestamp),
242
+ 'high': this.safeString (ticker, 'high'),
243
+ 'low': this.safeString (ticker, 'low'),
244
+ 'bid': undefined,
245
+ 'bidVolume': undefined,
246
+ 'ask': undefined,
247
+ 'askVolume': undefined,
248
+ 'vwap': undefined,
249
+ 'open': undefined,
250
+ 'close': last,
251
+ 'last': last,
252
+ 'previousClose': undefined,
253
+ 'change': undefined,
254
+ 'percentage': percentage,
255
+ 'average': undefined,
256
+ 'baseVolume': this.safeString (ticker, 'vol'),
257
+ 'quoteVolume': this.safeString (ticker, 'turnover'),
258
+ 'info': info,
259
+ }, market, false);
260
+ }
261
+
262
+ async fetchTicker (symbol, params = {}) {
263
+ await this.loadMarkets ();
264
+ const market = this.market (symbol);
265
+ const request = {
266
+ 'symbol': market['id'],
267
+ };
268
+ const response = await this.publicGetTicker (this.extend (request, params));
269
+ // {
270
+ // "symbol":"btc_usdt",
271
+ // "ticker":{
272
+ // "high":43416.06,
273
+ // "vol":7031.7427,
274
+ // "low":41804.26,
275
+ // "change":1.33,
276
+ // "turnover":300302447.81,
277
+ // "latest":43220.4
278
+ // },
279
+ // "timestamp":1642201617747
280
+ // }
281
+ return this.parseTicker (response, market);
282
+ }
283
+
284
+ async fetchTickers (symbols = undefined, params = {}) {
285
+ await this.loadMarkets ();
286
+ const request = {
287
+ 'symbol': 'all',
288
+ };
289
+ const response = await this.publicGetTicker (this.extend (request, params));
290
+ const result = {};
291
+ for (let i = 0; i < response.length; i++) {
292
+ const ticker = this.parseTicker (response[i]);
293
+ const symbol = ticker['symbol'];
294
+ result[symbol] = ticker;
295
+ }
296
+ return this.filterByArray (result, 'symbol', symbols);
297
+ }
298
+
299
+ async fetchOrderBook (symbol, limit = 60, params = {}) {
300
+ await this.loadMarkets ();
301
+ let size = 60;
302
+ if (limit !== undefined) {
303
+ size = Math.min (limit, size);
304
+ }
305
+ const request = {
306
+ 'symbol': this.marketId (symbol),
307
+ 'size': size,
308
+ };
309
+ const response = await this.publicGetDepth (this.extend (request, params));
310
+ return this.parseOrderBook (response, symbol);
311
+ }
312
+
313
+ parseTrade (trade, market = undefined) {
314
+ market = this.safeMarket (undefined, market);
315
+ const timestamp = this.safeInteger (trade, 'date_ms');
316
+ const priceString = this.safeString (trade, 'price');
317
+ const amountString = this.safeString (trade, 'amount');
318
+ const price = this.parseNumber (priceString);
319
+ const amount = this.parseNumber (amountString);
320
+ const cost = this.parseNumber (Precise.stringMul (priceString, amountString));
321
+ const id = this.safeString (trade, 'tid');
322
+ const type = undefined;
323
+ let side = this.safeString (trade, 'type');
324
+ side = side.replace ('_market', '');
325
+ return {
326
+ 'id': id,
327
+ 'info': this.safeValue (trade, 'info', trade),
328
+ 'timestamp': timestamp,
329
+ 'datetime': this.iso8601 (timestamp),
330
+ 'symbol': market['symbol'],
331
+ 'order': undefined,
332
+ 'type': type,
333
+ 'side': side,
334
+ 'takerOrMaker': undefined,
335
+ 'price': price,
336
+ 'amount': amount,
337
+ 'cost': cost,
338
+ 'fee': undefined,
339
+ };
340
+ }
341
+
342
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
343
+ await this.loadMarkets ();
344
+ const market = this.market (symbol);
345
+ const request = {
346
+ 'symbol': market['id'],
347
+ 'size': 100,
348
+ };
349
+ if (since !== undefined) {
350
+ request['time'] = parseInt (since);
351
+ }
352
+ if (limit !== undefined) {
353
+ request['size'] = limit;
354
+ }
355
+ const response = await this.publicGetTrades (this.extend (request, params));
356
+ return this.parseTrades (response, market, since, limit);
357
+ }
358
+
359
+ parseOHLCV (ohlcv, market = undefined) {
360
+ //
361
+ // [
362
+ // 1590969600,
363
+ // 0.02451657,
364
+ // 0.02452675,
365
+ // 0.02443701,
366
+ // 0.02447814,
367
+ // 238.38210000
368
+ // ]
369
+ //
370
+ return [
371
+ this.safeTimestamp (ohlcv, 0),
372
+ this.safeNumber (ohlcv, 1),
373
+ this.safeNumber (ohlcv, 2),
374
+ this.safeNumber (ohlcv, 3),
375
+ this.safeNumber (ohlcv, 4),
376
+ this.safeNumber (ohlcv, 5),
377
+ ];
378
+ }
379
+
380
+ async fetchOHLCV (symbol, timeframe = '5m', since = undefined, limit = 1000, params = {}) {
381
+ await this.loadMarkets ();
382
+ const market = this.market (symbol);
383
+ if (since === undefined) {
384
+ throw new ArgumentsRequired (this.id + ' fetchOHLCV() requires a `since` argument');
385
+ }
386
+ if (limit === undefined) {
387
+ throw new ArgumentsRequired (this.id + ' fetchOHLCV() requires a `limit` argument');
388
+ }
389
+ const request = {
390
+ 'symbol': market['id'],
391
+ 'type': this.timeframes[timeframe],
392
+ 'size': limit,
393
+ 'time': parseInt (since / 1000),
394
+ };
395
+ const response = await this.publicGetKline (this.extend (request, params));
396
+ //
397
+ // [
398
+ // [1590969600,0.02451657,0.02452675,0.02443701,0.02447814,238.38210000],
399
+ // [1590969660,0.02447814,0.02449883,0.02443209,0.02445973,212.40270000],
400
+ // [1590969720,0.02445973,0.02452067,0.02445909,0.02446151,266.16920000],
401
+ // ]
402
+ //
403
+ return this.parseOHLCVs (response, market, timeframe, since, limit);
404
+ }
405
+
406
+ parseBalance (response) {
407
+ const result = {
408
+ 'info': response,
409
+ 'timestamp': undefined,
410
+ 'datetime': undefined,
411
+ };
412
+ const info = this.safeValue (response, 'info', {});
413
+ const free = this.safeValue (info, 'free', {});
414
+ const freeze = this.safeValue (info, 'freeze', {});
415
+ const asset = this.safeValue (info, 'asset', {});
416
+ const currencyIds = Object.keys (free);
417
+ for (let i = 0; i < currencyIds.length; i++) {
418
+ const currencyId = currencyIds[i];
419
+ const code = this.safeCurrencyCode (currencyId);
420
+ const account = this.account ();
421
+ account['free'] = this.safeString (free, currencyId);
422
+ account['used'] = this.safeString (freeze, currencyId);
423
+ account['total'] = this.safeString (asset, currencyId);
424
+ result[code] = account;
425
+ }
426
+ return this.safeBalance (result);
427
+ }
428
+
429
+ async fetchBalance (params = {}) {
430
+ await this.loadMarkets ();
431
+ const response = await this.privatePostUserInfo (params);
432
+ //
433
+ // {
434
+ // "result":"true",
435
+ // "info":{
436
+ // "freeze":{
437
+ // "iog":"0.00000000",
438
+ // "ssc":"0.00000000",
439
+ // "eon":"0.00000000",
440
+ // },
441
+ // "asset":{
442
+ // "iog":"0.00000000",
443
+ // "ssc":"0.00000000",
444
+ // "eon":"0.00000000",
445
+ // },
446
+ // "free":{
447
+ // "iog":"0.00000000",
448
+ // "ssc":"0.00000000",
449
+ // "eon":"0.00000000",
450
+ // },
451
+ // }
452
+ // }
453
+ //
454
+ return this.parseBalance (response);
455
+ }
456
+
457
+ parseOrderStatus (status) {
458
+ const statuses = {
459
+ '-1': 'cancelled', // cancelled
460
+ '0': 'open', // not traded
461
+ '1': 'open', // partial deal
462
+ '2': 'closed', // complete deal
463
+ '4': 'closed', // disposal processing
464
+ };
465
+ return this.safeString (statuses, status);
466
+ }
467
+
468
+ parseOrder (order, market = undefined) {
469
+ //
470
+ // {
471
+ // "symbol":"eth_btc",
472
+ // "amount":10.000000,
473
+ // "create_time":1484289832081,
474
+ // "price":5000.000000,
475
+ // "avg_price":5277.301200,
476
+ // "type":"sell",
477
+ // "order_id":"ab704110-af0d-48fd-a083-c218f19a4a55",
478
+ // "deal_amount":10.000000,
479
+ // "status":2
480
+ // }
481
+ //
482
+ const marketId = this.safeString (order, 'symbol');
483
+ const symbol = this.safeSymbol (marketId, market, '_');
484
+ const timestamp = this.safeInteger (order, 'create_time');
485
+ // Limit Order Request Returns: Order Price
486
+ // Market Order Returns: cny amount of market order
487
+ const price = this.safeString (order, 'price');
488
+ const amount = this.safeString (order, 'amount');
489
+ const filled = this.safeString (order, 'deal_amount');
490
+ const average = this.safeString (order, 'avg_price');
491
+ const status = this.parseOrderStatus (this.safeString (order, 'status'));
492
+ const id = this.safeString (order, 'order_id');
493
+ const type = this.safeString (order, 'order_type');
494
+ const side = this.safeString (order, 'type');
495
+ return this.safeOrder ({
496
+ 'id': id,
497
+ 'clientOrderId': undefined,
498
+ 'datetime': this.iso8601 (timestamp),
499
+ 'timestamp': timestamp,
500
+ 'lastTradeTimestamp': undefined,
501
+ 'status': status,
502
+ 'symbol': symbol,
503
+ 'type': type,
504
+ 'timeInForce': undefined,
505
+ 'postOnly': undefined,
506
+ 'side': side,
507
+ 'price': price,
508
+ 'stopPrice': undefined,
509
+ 'cost': undefined,
510
+ 'amount': amount,
511
+ 'filled': filled,
512
+ 'remaining': undefined,
513
+ 'trades': undefined,
514
+ 'fee': undefined,
515
+ 'info': this.safeValue (order, 'info', order),
516
+ 'average': average,
517
+ }, market);
518
+ }
519
+
520
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
521
+ await this.loadMarkets ();
522
+ const market = this.market (symbol);
523
+ let order = {
524
+ 'symbol': market['id'],
525
+ 'type': side,
526
+ 'amount': amount,
527
+ };
528
+ if (type === 'market') {
529
+ order['type'] += '_market';
530
+ } else {
531
+ order['price'] = price;
532
+ }
533
+ const response = await this.privatePostCreateOrder (this.extend (order, params));
534
+ order = this.omit (order, 'type');
535
+ order['order_id'] = response['order_id'];
536
+ order['type'] = side;
537
+ order['order_type'] = type;
538
+ order['create_time'] = this.milliseconds ();
539
+ order['info'] = response;
540
+ return this.parseOrder (order, market);
541
+ }
542
+
543
+ async cancelOrder (id, symbol = undefined, params = {}) {
544
+ await this.loadMarkets ();
545
+ const market = this.market (symbol);
546
+ const request = {
547
+ 'symbol': market['id'],
548
+ 'order_id': id,
549
+ };
550
+ const response = await this.privatePostCancelOrder (this.extend (request, params));
551
+ return response;
552
+ }
553
+
554
+ async fetchOrder (id, symbol = undefined, params = {}) {
555
+ // Id can be a list of ids delimited by a comma
556
+ await this.loadMarkets ();
557
+ const market = this.market (symbol);
558
+ const request = {
559
+ 'symbol': market['id'],
560
+ 'order_id': id,
561
+ };
562
+ const response = await this.privatePostOrdersInfo (this.extend (request, params));
563
+ const data = this.safeValue (response, 'orders', []);
564
+ const orders = this.parseOrders (data, market);
565
+ const numOrders = orders.length;
566
+ if (numOrders === 1) {
567
+ return orders[0];
568
+ } else {
569
+ return orders;
570
+ }
571
+ }
572
+
573
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
574
+ await this.loadMarkets ();
575
+ if (limit === undefined) {
576
+ limit = 100;
577
+ }
578
+ const market = this.market (symbol);
579
+ const request = {
580
+ 'symbol': market['id'],
581
+ 'current_page': 1,
582
+ 'page_length': limit,
583
+ };
584
+ const response = await this.privatePostOrdersInfoHistory (this.extend (request, params));
585
+ const data = this.safeValue (response, 'orders', []);
586
+ return this.parseOrders (data, undefined, since, limit);
587
+ }
588
+
589
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
590
+ await this.loadMarkets ();
591
+ if (symbol !== undefined) {
592
+ const market = this.market (symbol);
593
+ symbol = market['symbol'];
594
+ }
595
+ const orders = await this.fetchOrders (symbol, since, limit, params);
596
+ const closed = this.filterBy (orders, 'status', 'closed');
597
+ const canceled = this.filterBy (orders, 'status', 'cancelled'); // cancelled orders may be partially filled
598
+ const allOrders = this.arrayConcat (closed, canceled);
599
+ return this.filterBySymbolSinceLimit (allOrders, symbol, since, limit);
600
+ }
601
+
602
+ async withdraw (code, amount, address, tag = undefined, params = {}) {
603
+ [ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
604
+ // mark and fee are optional params, mark is a note and must be less than 255 characters
605
+ this.checkAddress (address);
606
+ await this.loadMarkets ();
607
+ const currency = this.currency (code);
608
+ const request = {
609
+ 'assetCode': currency['id'],
610
+ 'amount': amount,
611
+ 'account': address,
612
+ };
613
+ if (tag !== undefined) {
614
+ request['memo'] = tag;
615
+ }
616
+ const response = this.privatePostWithdraw (this.extend (request, params));
617
+ //
618
+ // {
619
+ // 'result': 'true',
620
+ // 'withdrawId': 90082,
621
+ // 'fee':0.001
622
+ // }
623
+ //
624
+ return this.parseTransaction (response, currency);
625
+ }
626
+
627
+ parseTransaction (transaction, currency = undefined) {
628
+ //
629
+ // withdraw
630
+ //
631
+ // {
632
+ // 'result': 'true',
633
+ // 'withdrawId': 90082,
634
+ // 'fee':0.001
635
+ // }
636
+ //
637
+ currency = this.safeCurrency (undefined, currency);
638
+ return {
639
+ 'id': this.safeString2 (transaction, 'id', 'withdrawId'),
640
+ 'txid': undefined,
641
+ 'timestamp': undefined,
642
+ 'datetime': undefined,
643
+ 'network': undefined,
644
+ 'addressFrom': undefined,
645
+ 'address': undefined,
646
+ 'addressTo': undefined,
647
+ 'amount': undefined,
648
+ 'type': undefined,
649
+ 'currency': currency['code'],
650
+ 'status': undefined,
651
+ 'updated': undefined,
652
+ 'tagFrom': undefined,
653
+ 'tag': undefined,
654
+ 'tagTo': undefined,
655
+ 'comment': undefined,
656
+ 'fee': undefined,
657
+ 'info': transaction,
658
+ };
659
+ }
660
+
661
+ convertSecretToPem (secret) {
662
+ const lineLength = 64;
663
+ const secretLength = secret.length - 0;
664
+ let numLines = parseInt (secretLength / lineLength);
665
+ numLines = this.sum (numLines, 1);
666
+ let pem = "-----BEGIN PRIVATE KEY-----\n"; // eslint-disable-line
667
+ for (let i = 0; i < numLines; i++) {
668
+ const start = i * lineLength;
669
+ const end = this.sum (start, lineLength);
670
+ pem += this.secret.slice (start, end) + "\n"; // eslint-disable-line
671
+ }
672
+ return pem + '-----END PRIVATE KEY-----';
673
+ }
674
+
675
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
676
+ const query = this.omit (params, this.extractParams (path));
677
+ let url = this.urls['api'] + '/' + this.version + '/' + this.implodeParams (path, params);
678
+ // Every endpoint ends with ".do"
679
+ url += '.do';
680
+ if (api === 'public') {
681
+ if (Object.keys (query).length) {
682
+ url += '?' + this.urlencode (query);
683
+ }
684
+ } else {
685
+ this.checkRequiredCredentials ();
686
+ const query = this.keysort (this.extend ({
687
+ 'api_key': this.apiKey,
688
+ }, params));
689
+ const queryString = this.rawencode (query);
690
+ const message = this.hash (this.encode (queryString)).toUpperCase ();
691
+ const cacheSecretAsPem = this.safeValue (this.options, 'cacheSecretAsPem', true);
692
+ let pem = undefined;
693
+ if (cacheSecretAsPem) {
694
+ pem = this.safeValue (this.options, 'pem');
695
+ if (pem === undefined) {
696
+ pem = this.convertSecretToPem (this.secret);
697
+ this.options['pem'] = pem;
698
+ }
699
+ } else {
700
+ pem = this.convertSecretToPem (this.secret);
701
+ }
702
+ const sign = this.binaryToBase64 (this.rsa (message, this.encode (pem), 'RS256'));
703
+ query['sign'] = sign;
704
+ body = this.urlencode (query);
705
+ headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
706
+ }
707
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
708
+ }
709
+
710
+ handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
711
+ if (response === undefined) {
712
+ return;
713
+ }
714
+ const success = this.safeString (response, 'result');
715
+ if (success === 'false') {
716
+ const errorCode = this.safeString (response, 'error_code');
717
+ const message = this.safeString ({
718
+ '10000': 'Internal error',
719
+ '10001': 'The required parameters can not be empty',
720
+ '10002': 'verification failed',
721
+ '10003': 'Illegal parameters',
722
+ '10004': 'User requests are too frequent',
723
+ '10005': 'Key does not exist',
724
+ '10006': 'user does not exist',
725
+ '10007': 'Invalid signature',
726
+ '10008': 'This currency pair is not supported',
727
+ '10009': 'Limit orders can not be missing orders and the number of orders',
728
+ '10010': 'Order price or order quantity must be greater than 0',
729
+ '10011': 'Market orders can not be missing the amount of the order',
730
+ '10012': 'market sell orders can not be missing orders',
731
+ '10013': 'is less than the minimum trading position 0.001',
732
+ '10014': 'Account number is not enough',
733
+ '10015': 'The order type is wrong',
734
+ '10016': 'Account balance is not enough',
735
+ '10017': 'Abnormal server',
736
+ '10018': 'order inquiry can not be more than 50 less than one',
737
+ '10019': 'withdrawal orders can not be more than 3 less than one',
738
+ '10020': 'less than the minimum amount of the transaction limit of 0.001',
739
+ '10022': 'Insufficient key authority',
740
+ }, errorCode, this.json (response));
741
+ const ErrorClass = this.safeValue ({
742
+ '10002': AuthenticationError,
743
+ '10004': DDoSProtection,
744
+ '10005': AuthenticationError,
745
+ '10006': AuthenticationError,
746
+ '10007': AuthenticationError,
747
+ '10009': InvalidOrder,
748
+ '10010': InvalidOrder,
749
+ '10011': InvalidOrder,
750
+ '10012': InvalidOrder,
751
+ '10013': InvalidOrder,
752
+ '10014': InvalidOrder,
753
+ '10015': InvalidOrder,
754
+ '10016': InvalidOrder,
755
+ '10022': AuthenticationError,
756
+ }, errorCode, ExchangeError);
757
+ throw new ErrorClass (message);
758
+ }
759
+ }
760
+ };