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/bibox.js ADDED
@@ -0,0 +1,1407 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, AccountSuspended, ArgumentsRequired, AuthenticationError, DDoSProtection, ExchangeNotAvailable, InvalidOrder, OrderNotFound, PermissionDenied, InsufficientFunds, BadSymbol, RateLimitExceeded, BadRequest } = require ('./base/errors');
7
+ const Precise = require ('./base/Precise');
8
+
9
+ // ---------------------------------------------------------------------------
10
+
11
+ module.exports = class bibox extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'bibox',
15
+ 'name': 'Bibox',
16
+ 'countries': [ 'CN', 'US', 'KR' ],
17
+ 'version': 'v1',
18
+ 'hostname': 'bibox.com',
19
+ 'has': {
20
+ 'CORS': undefined,
21
+ 'spot': true,
22
+ 'margin': undefined, // has but unimplemented
23
+ 'swap': undefined, // has but unimplemented
24
+ 'future': undefined,
25
+ 'option': undefined,
26
+ 'cancelOrder': true,
27
+ 'createMarketOrder': undefined, // or they will return https://github.com/ccxt/ccxt/issues/2338
28
+ 'createOrder': true,
29
+ 'fetchBalance': true,
30
+ 'fetchBorrowRate': false,
31
+ 'fetchBorrowRates': false,
32
+ 'fetchClosedOrders': true,
33
+ 'fetchCurrencies': true,
34
+ 'fetchDepositAddress': true,
35
+ 'fetchDeposits': true,
36
+ 'fetchFundingFees': true,
37
+ 'fetchMarkets': true,
38
+ 'fetchMyTrades': true,
39
+ 'fetchOHLCV': true,
40
+ 'fetchOpenOrders': true,
41
+ 'fetchOrder': true,
42
+ 'fetchOrderBook': true,
43
+ 'fetchTicker': true,
44
+ 'fetchTickers': true,
45
+ 'fetchTrades': true,
46
+ 'fetchTradingFee': false,
47
+ 'fetchTradingFees': false,
48
+ 'fetchWithdrawals': true,
49
+ 'withdraw': true,
50
+ },
51
+ 'timeframes': {
52
+ '1m': '1min',
53
+ '5m': '5min',
54
+ '15m': '15min',
55
+ '30m': '30min',
56
+ '1h': '1hour',
57
+ '2h': '2hour',
58
+ '4h': '4hour',
59
+ '6h': '6hour',
60
+ '12h': '12hour',
61
+ '1d': 'day',
62
+ '1w': 'week',
63
+ },
64
+ 'urls': {
65
+ 'logo': 'https://user-images.githubusercontent.com/51840849/77257418-3262b000-6c85-11ea-8fb8-20bdf20b3592.jpg',
66
+ 'api': 'https://api.{hostname}',
67
+ 'www': 'https://www.bibox365.com',
68
+ 'doc': [
69
+ 'https://biboxcom.github.io/en/',
70
+ ],
71
+ 'fees': 'https://bibox.zendesk.com/hc/en-us/articles/360002336133',
72
+ 'referral': 'https://w2.bibox365.com/login/register?invite_code=05Kj3I',
73
+ },
74
+ 'api': {
75
+ 'public': {
76
+ 'post': [
77
+ // TODO: rework for full endpoint/cmd paths here
78
+ 'mdata',
79
+ ],
80
+ 'get': [
81
+ 'cquery',
82
+ 'mdata',
83
+ 'cdata',
84
+ 'orderpending',
85
+ ],
86
+ },
87
+ 'private': {
88
+ 'post': [
89
+ 'cquery',
90
+ 'ctrade',
91
+ 'user',
92
+ 'orderpending',
93
+ 'transfer',
94
+ ],
95
+ },
96
+ 'v2private': {
97
+ 'post': [
98
+ 'assets/transfer/spot',
99
+ ],
100
+ },
101
+ },
102
+ 'fees': {
103
+ 'trading': {
104
+ 'tierBased': false,
105
+ 'percentage': true,
106
+ 'taker': this.parseNumber ('0.002'),
107
+ 'maker': this.parseNumber ('0.001'),
108
+ },
109
+ 'funding': {
110
+ 'tierBased': false,
111
+ 'percentage': false,
112
+ 'withdraw': {},
113
+ 'deposit': {},
114
+ },
115
+ },
116
+ 'exceptions': {
117
+ '2011': AccountSuspended, // Account is locked
118
+ '2015': AuthenticationError, // Google authenticator is wrong
119
+ '2021': InsufficientFunds, // Insufficient balance available for withdrawal
120
+ '2027': InsufficientFunds, // Insufficient balance available (for trade)
121
+ '2033': OrderNotFound, // operation failed! Orders have been completed or revoked
122
+ '2065': InvalidOrder, // Precatory price is exorbitant, please reset
123
+ '2066': InvalidOrder, // Precatory price is low, please reset
124
+ '2067': InvalidOrder, // Does not support market orders
125
+ '2068': InvalidOrder, // The number of orders can not be less than
126
+ '2078': InvalidOrder, // unvalid order price
127
+ '2085': InvalidOrder, // Order quantity is too small
128
+ '2091': RateLimitExceeded, // request is too frequency, please try again later
129
+ '2092': InvalidOrder, // Minimum amount not met
130
+ '2131': InvalidOrder, // The order quantity cannot be greater than
131
+ '3000': BadRequest, // Requested parameter incorrect
132
+ '3002': BadRequest, // Parameter cannot be null
133
+ '3012': AuthenticationError, // invalid apiKey
134
+ '3016': BadSymbol, // Trading pair error
135
+ '3024': PermissionDenied, // wrong apikey permissions
136
+ '3025': AuthenticationError, // signature failed
137
+ '4000': ExchangeNotAvailable, // current network is unstable
138
+ '4003': DDoSProtection, // server busy please try again later
139
+ },
140
+ 'commonCurrencies': {
141
+ 'APENFT(NFT)': 'NFT',
142
+ 'BOX': 'DefiBox',
143
+ 'BPT': 'BlockPool Token',
144
+ 'GMT': 'GMT Token',
145
+ 'KEY': 'Bihu',
146
+ 'MTC': 'MTC Mesh Network', // conflict with MTC Docademic doc.com Token https://github.com/ccxt/ccxt/issues/6081 https://github.com/ccxt/ccxt/issues/3025
147
+ 'NFT': 'NFT Protocol',
148
+ 'PAI': 'PCHAIN',
149
+ 'REVO': 'Revo Network',
150
+ 'STAR': 'Starbase',
151
+ 'TERN': 'Ternio-ERC20',
152
+ },
153
+ });
154
+ }
155
+
156
+ async fetchMarkets (params = {}) {
157
+ const request = {
158
+ 'cmd': 'pairList',
159
+ };
160
+ const response = await this.publicGetMdata (this.extend (request, params));
161
+ //
162
+ // {
163
+ // "result": [
164
+ // {
165
+ // "id":1,
166
+ // "pair":"BIX_BTC",
167
+ // "pair_type":0,
168
+ // "area_id":7,
169
+ // "is_hide":0,
170
+ // "decimal":8,
171
+ // "amount_scale":4
172
+ // }
173
+ // ],
174
+ // "cmd":"pairList",
175
+ // "ver":"1.1"
176
+ // }
177
+ //
178
+ const markets = this.safeValue (response, 'result');
179
+ const request2 = {
180
+ 'cmd': 'tradeLimit',
181
+ };
182
+ const response2 = await this.publicGetOrderpending (this.extend (request2, params));
183
+ //
184
+ // {
185
+ // result: {
186
+ // min_trade_price: { default: '0.00000001', USDT: '0.0001', DAI: '0.0001' },
187
+ // min_trade_amount: { default: '0.0001' },
188
+ // min_trade_money: {
189
+ // USDT: '1',
190
+ // USDC: '1',
191
+ // DAI: '1',
192
+ // GUSD: '1',
193
+ // BIX: '3',
194
+ // BTC: '0.0002',
195
+ // ETH: '0.005'
196
+ // }
197
+ // },
198
+ // cmd: 'tradeLimit'
199
+ // }
200
+ //
201
+ const result2 = this.safeValue (response2, 'result', {});
202
+ const minCosts = this.safeValue (result2, 'min_trade_money', {});
203
+ const result = [];
204
+ for (let i = 0; i < markets.length; i++) {
205
+ const market = markets[i];
206
+ const numericId = this.safeInteger (market, 'id');
207
+ const id = this.safeString (market, 'pair');
208
+ let baseId = undefined;
209
+ let quoteId = undefined;
210
+ if (id !== undefined) {
211
+ const parts = id.split ('_');
212
+ baseId = this.safeString (parts, 0);
213
+ quoteId = this.safeString (parts, 1);
214
+ }
215
+ const base = this.safeCurrencyCode (baseId);
216
+ const quote = this.safeCurrencyCode (quoteId);
217
+ const symbol = base + '/' + quote;
218
+ const type = 'spot';
219
+ const spot = true;
220
+ const areaId = this.safeInteger (market, 'area_id');
221
+ if (areaId === 16) {
222
+ // TODO: update to v3 api
223
+ continue;
224
+ }
225
+ result.push ({
226
+ 'id': id,
227
+ 'numericId': numericId,
228
+ 'symbol': symbol,
229
+ 'base': base,
230
+ 'quote': quote,
231
+ 'settle': undefined,
232
+ 'baseId': baseId,
233
+ 'quoteId': quoteId,
234
+ 'settleId': undefined,
235
+ 'type': type,
236
+ 'spot': spot,
237
+ 'margin': false,
238
+ 'swap': false,
239
+ 'future': false,
240
+ 'option': false,
241
+ 'active': undefined,
242
+ 'contract': false,
243
+ 'linear': undefined,
244
+ 'inverse': undefined,
245
+ 'contractSize': undefined,
246
+ 'expiry': undefined,
247
+ 'expiryDatetime': undefined,
248
+ 'strike': undefined,
249
+ 'optionType': undefined,
250
+ 'precision': {
251
+ 'amount': this.safeInteger (market, 'amount_scale'),
252
+ 'price': this.safeInteger (market, 'decimal'),
253
+ },
254
+ 'limits': {
255
+ 'leverage': {
256
+ 'min': undefined,
257
+ 'max': undefined,
258
+ },
259
+ 'amount': {
260
+ 'min': undefined,
261
+ 'max': undefined,
262
+ },
263
+ 'price': {
264
+ 'min': undefined,
265
+ 'max': undefined,
266
+ },
267
+ 'cost': {
268
+ 'min': this.safeNumber (minCosts, quoteId),
269
+ 'max': undefined,
270
+ },
271
+ },
272
+ 'info': market,
273
+ });
274
+ }
275
+ return result;
276
+ }
277
+
278
+ parseTicker (ticker, market = undefined) {
279
+ // we don't set values that are not defined by the exchange
280
+ const timestamp = this.safeInteger (ticker, 'timestamp');
281
+ let marketId = undefined;
282
+ const baseId = this.safeString (ticker, 'coin_symbol');
283
+ const quoteId = this.safeString (ticker, 'currency_symbol');
284
+ if ((baseId !== undefined) && (quoteId !== undefined)) {
285
+ marketId = baseId + '_' + quoteId;
286
+ }
287
+ market = this.safeMarket (marketId, market);
288
+ const last = this.safeString (ticker, 'last');
289
+ const change = this.safeString (ticker, 'change');
290
+ const baseVolume = this.safeString2 (ticker, 'vol', 'vol24H');
291
+ let percentage = this.safeString (ticker, 'percent');
292
+ if (percentage !== undefined) {
293
+ percentage = percentage.replace ('%', '');
294
+ }
295
+ return this.safeTicker ({
296
+ 'symbol': market['symbol'],
297
+ 'timestamp': timestamp,
298
+ 'datetime': this.iso8601 (timestamp),
299
+ 'high': this.safeString (ticker, 'high'),
300
+ 'low': this.safeString (ticker, 'low'),
301
+ 'bid': this.safeString (ticker, 'buy'),
302
+ 'bidVolume': this.safeString (ticker, 'buy_amount'),
303
+ 'ask': this.safeString (ticker, 'sell'),
304
+ 'askVolume': this.safeString (ticker, 'sell_amount'),
305
+ 'vwap': undefined,
306
+ 'open': undefined,
307
+ 'close': last,
308
+ 'last': last,
309
+ 'previousClose': undefined,
310
+ 'change': change,
311
+ 'percentage': percentage,
312
+ 'average': undefined,
313
+ 'baseVolume': baseVolume,
314
+ 'quoteVolume': this.safeString (ticker, 'amount'),
315
+ 'info': ticker,
316
+ }, market, false);
317
+ }
318
+
319
+ async fetchTicker (symbol, params = {}) {
320
+ await this.loadMarkets ();
321
+ const market = this.market (symbol);
322
+ const request = {
323
+ 'cmd': 'ticker',
324
+ 'pair': market['id'],
325
+ };
326
+ const response = await this.publicGetMdata (this.extend (request, params));
327
+ return this.parseTicker (response['result'], market);
328
+ }
329
+
330
+ async fetchTickers (symbols = undefined, params = {}) {
331
+ const request = {
332
+ 'cmd': 'marketAll',
333
+ };
334
+ const response = await this.publicGetMdata (this.extend (request, params));
335
+ const tickers = this.parseTickers (response['result'], symbols);
336
+ const result = this.indexBy (tickers, 'symbol');
337
+ return this.filterByArray (result, 'symbol', symbols);
338
+ }
339
+
340
+ parseTrade (trade, market = undefined) {
341
+ const timestamp = this.safeInteger2 (trade, 'time', 'createdAt');
342
+ let side = this.safeInteger2 (trade, 'side', 'order_side');
343
+ side = (side === 1) ? 'buy' : 'sell';
344
+ let marketId = this.safeString (trade, 'pair');
345
+ if (marketId === undefined) {
346
+ const baseId = this.safeString (trade, 'coin_symbol');
347
+ const quoteId = this.safeString (trade, 'currency_symbol');
348
+ if ((baseId !== undefined) && (quoteId !== undefined)) {
349
+ marketId = baseId + '_' + quoteId;
350
+ }
351
+ }
352
+ market = this.safeMarket (marketId, market);
353
+ const priceString = this.safeString (trade, 'price');
354
+ const amountString = this.safeString (trade, 'amount');
355
+ let fee = undefined;
356
+ const feeCostString = this.safeString (trade, 'fee');
357
+ if (feeCostString !== undefined) {
358
+ const feeCurrencyId = this.safeString (trade, 'fee_symbol');
359
+ const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
360
+ fee = {
361
+ 'cost': Precise.stringNeg (feeCostString),
362
+ 'currency': feeCurrencyCode,
363
+ };
364
+ }
365
+ const id = this.safeString (trade, 'id');
366
+ return this.safeTrade ({
367
+ 'info': trade,
368
+ 'id': id,
369
+ 'order': undefined, // Bibox does not have it (documented) yet
370
+ 'timestamp': timestamp,
371
+ 'datetime': this.iso8601 (timestamp),
372
+ 'symbol': market['symbol'],
373
+ 'type': 'limit',
374
+ 'takerOrMaker': undefined,
375
+ 'side': side,
376
+ 'price': priceString,
377
+ 'amount': amountString,
378
+ 'cost': undefined,
379
+ 'fee': fee,
380
+ }, market);
381
+ }
382
+
383
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
384
+ await this.loadMarkets ();
385
+ const market = this.market (symbol);
386
+ const request = {
387
+ 'cmd': 'deals',
388
+ 'pair': market['id'],
389
+ };
390
+ if (limit !== undefined) {
391
+ request['size'] = limit; // default = 200
392
+ }
393
+ const response = await this.publicGetMdata (this.extend (request, params));
394
+ return this.parseTrades (response['result'], market, since, limit);
395
+ }
396
+
397
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
398
+ await this.loadMarkets ();
399
+ const market = this.market (symbol);
400
+ const request = {
401
+ 'cmd': 'depth',
402
+ 'pair': market['id'],
403
+ };
404
+ if (limit !== undefined) {
405
+ request['size'] = limit; // default = 200
406
+ }
407
+ const response = await this.publicGetMdata (this.extend (request, params));
408
+ return this.parseOrderBook (response['result'], symbol, this.safeNumber (response['result'], 'update_time'), 'bids', 'asks', 'price', 'volume');
409
+ }
410
+
411
+ parseOHLCV (ohlcv, market = undefined) {
412
+ //
413
+ // {
414
+ // "time":1591448220000,
415
+ // "open":"0.02507029",
416
+ // "high":"0.02507029",
417
+ // "low":"0.02506349",
418
+ // "close":"0.02506349",
419
+ // "vol":"5.92000000"
420
+ // }
421
+ //
422
+ return [
423
+ this.safeInteger (ohlcv, 'time'),
424
+ this.safeNumber (ohlcv, 'open'),
425
+ this.safeNumber (ohlcv, 'high'),
426
+ this.safeNumber (ohlcv, 'low'),
427
+ this.safeNumber (ohlcv, 'close'),
428
+ this.safeNumber (ohlcv, 'vol'),
429
+ ];
430
+ }
431
+
432
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = 1000, params = {}) {
433
+ await this.loadMarkets ();
434
+ const market = this.market (symbol);
435
+ const request = {
436
+ 'cmd': 'kline',
437
+ 'pair': market['id'],
438
+ 'period': this.timeframes[timeframe],
439
+ 'size': limit,
440
+ };
441
+ const response = await this.publicGetMdata (this.extend (request, params));
442
+ //
443
+ // {
444
+ // "result":[
445
+ // {"time":1591448220000,"open":"0.02507029","high":"0.02507029","low":"0.02506349","close":"0.02506349","vol":"5.92000000"},
446
+ // {"time":1591448280000,"open":"0.02506449","high":"0.02506975","low":"0.02506108","close":"0.02506843","vol":"5.72000000"},
447
+ // {"time":1591448340000,"open":"0.02506698","high":"0.02506698","low":"0.02506452","close":"0.02506519","vol":"4.86000000"},
448
+ // ],
449
+ // "cmd":"kline",
450
+ // "ver":"1.1"
451
+ // }
452
+ //
453
+ const result = this.safeValue (response, 'result', []);
454
+ return this.parseOHLCVs (result, market, timeframe, since, limit);
455
+ }
456
+
457
+ async fetchCurrencies (params = {}) {
458
+ if (this.checkRequiredCredentials (false)) {
459
+ return await this.fetchCurrenciesPrivate (params);
460
+ } else {
461
+ return await this.fetchCurrenciesPublic (params);
462
+ }
463
+ }
464
+
465
+ async fetchCurrenciesPublic (params = {}) {
466
+ const request = {
467
+ 'cmd': 'currencies',
468
+ };
469
+ const response = await this.publicGetCdata (this.extend (request, params));
470
+ //
471
+ // publicGetCdata
472
+ //
473
+ // {
474
+ // "result":[
475
+ // {
476
+ // "symbol":"BTC",
477
+ // "name":"BTC",
478
+ // "valid_decimals":8,
479
+ // "original_decimals":8,
480
+ // "is_erc20":0,
481
+ // "enable_withdraw":1,
482
+ // "enable_deposit":1,
483
+ // "withdraw_min":0.005,
484
+ // "describe_summary":"[{\"lang\":\"zh-cn\",\"text\":\"Bitcoin 比特币的概念最初由中本聪在2009年提出,是点对点的基于 SHA-256 算法的一种P2P形式的数字货币,点对点的传输意味着一个去中心化的支付系统。\"},{\"lang\":\"en-ww\",\"text\":\"Bitcoin is a digital asset and a payment system invented by Satoshi Nakamoto who published a related paper in 2008 and released it as open-source software in 2009. The system featured as peer-to-peer; users can transact directly without an intermediary.\"}]"
485
+ // }
486
+ // ],
487
+ // "cmd":"currencies"
488
+ // }
489
+ //
490
+ const currencies = this.safeValue (response, 'result');
491
+ const result = {};
492
+ for (let i = 0; i < currencies.length; i++) {
493
+ const currency = currencies[i];
494
+ const id = this.safeString (currency, 'symbol');
495
+ const name = this.safeString (currency, 'name'); // contains hieroglyphs causing python ASCII bug
496
+ const code = this.safeCurrencyCode (id);
497
+ const precision = this.safeInteger (currency, 'valid_decimals');
498
+ const deposit = this.safeValue (currency, 'enable_deposit');
499
+ const withdraw = this.safeValue (currency, 'enable_withdraw');
500
+ const active = (deposit && withdraw);
501
+ result[code] = {
502
+ 'id': id,
503
+ 'code': code,
504
+ 'info': currency,
505
+ 'name': name,
506
+ 'active': active,
507
+ 'deposit': deposit,
508
+ 'withdraw': withdraw,
509
+ 'fee': undefined,
510
+ 'precision': precision,
511
+ 'limits': {
512
+ 'amount': {
513
+ 'min': Math.pow (10, -precision),
514
+ 'max': undefined,
515
+ },
516
+ 'withdraw': {
517
+ 'min': this.safeNumber (currency, 'withdraw_min'),
518
+ 'max': undefined,
519
+ },
520
+ },
521
+ };
522
+ }
523
+ return result;
524
+ }
525
+
526
+ async fetchCurrenciesPrivate (params = {}) {
527
+ if (!this.checkRequiredCredentials (false)) {
528
+ throw new AuthenticationError (this.id + " fetchCurrencies is an authenticated endpoint, therefore it requires 'apiKey' and 'secret' credentials. If you don't need currency details, set exchange.has['fetchCurrencies'] = false before calling its methods.");
529
+ }
530
+ const request = {
531
+ 'cmd': 'transfer/coinList',
532
+ 'body': {},
533
+ };
534
+ const response = await this.privatePostTransfer (this.extend (request, params));
535
+ //
536
+ // {
537
+ // "result":[
538
+ // {
539
+ // "result":[
540
+ // {
541
+ // "totalBalance":"14.60987476",
542
+ // "balance":"14.60987476",
543
+ // "freeze":"0.00000000",
544
+ // "id":60,
545
+ // "symbol":"USDT",
546
+ // "icon_url":"/appimg/USDT_icon.png",
547
+ // "describe_url":"[{\"lang\":\"zh-cn\",\"link\":\"https://bibox.zendesk.com/hc/zh-cn/articles/115004798234\"},{\"lang\":\"en-ww\",\"link\":\"https://bibox.zendesk.com/hc/en-us/articles/115004798234\"}]",
548
+ // "name":"USDT",
549
+ // "enable_withdraw":1,
550
+ // "enable_deposit":1,
551
+ // "enable_transfer":1,
552
+ // "confirm_count":2,
553
+ // "is_erc20":1,
554
+ // "forbid_info":null,
555
+ // "describe_summary":"[{\"lang\":\"zh-cn\",\"text\":\"USDT 是 Tether 公司推出的基于稳定价值货币美元(USD)的代币 Tether USD(简称USDT),1USDT=1美元,用户可以随时使用 USDT 与 USD 进行1:1的兑换。\"},{\"lang\":\"en-ww\",\"text\":\"USDT is a cryptocurrency asset issued on the Bitcoin blockchain via the Omni Layer Protocol. Each USDT unit is backed by a U.S Dollar held in the reserves of the Tether Limited and can be redeemed through the Tether Platform.\"}]",
556
+ // "total_amount":4776930644,
557
+ // "supply_amount":4642367414,
558
+ // "price":"--",
559
+ // "contract_father":"OMNI",
560
+ // "supply_time":"--",
561
+ // "comment":null,
562
+ // "chain_type":"OMNI",
563
+ // "general_name":"USDT",
564
+ // "contract":"31",
565
+ // "original_decimals":8,
566
+ // "deposit_type":0,
567
+ // "hasCobo":0,
568
+ // "BTCValue":"0.00027116",
569
+ // "CNYValue":"90.36087919",
570
+ // "USDValue":"14.61090236",
571
+ // "children":[
572
+ // {"type":"ERC20","symbol":"eUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":13},
573
+ // {"type":"TRC20","symbol":"tUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":20},
574
+ // {"type":"OMNI","symbol":"USDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":2},
575
+ // {"type":"HECO","symbol":"hUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":12},
576
+ // {"type":"BSC(BEP20)","symbol":"bUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":5},
577
+ // {"type":"HPB","symbol":"pUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":20}
578
+ // ]
579
+ // }
580
+ // ],
581
+ // "cmd":"transfer/coinList"
582
+ // }
583
+ // ]
584
+ // }
585
+ //
586
+ const outerResults = this.safeValue (response, 'result');
587
+ const firstResult = this.safeValue (outerResults, 0, {});
588
+ const currencies = this.safeValue (firstResult, 'result');
589
+ const result = {};
590
+ for (let i = 0; i < currencies.length; i++) {
591
+ const currency = currencies[i];
592
+ const id = this.safeString (currency, 'symbol');
593
+ const name = currency['name']; // contains hieroglyphs causing python ASCII bug
594
+ const code = this.safeCurrencyCode (id);
595
+ const precision = 8;
596
+ const deposit = this.safeValue (currency, 'enable_deposit');
597
+ const withdraw = this.safeValue (currency, 'enable_withdraw');
598
+ const active = (deposit && withdraw);
599
+ result[code] = {
600
+ 'id': id,
601
+ 'code': code,
602
+ 'info': currency,
603
+ 'name': name,
604
+ 'active': active,
605
+ 'fee': undefined,
606
+ 'precision': precision,
607
+ 'limits': {
608
+ 'amount': {
609
+ 'min': Math.pow (10, -precision),
610
+ 'max': Math.pow (10, precision),
611
+ },
612
+ 'withdraw': {
613
+ 'min': undefined,
614
+ 'max': Math.pow (10, precision),
615
+ },
616
+ },
617
+ };
618
+ }
619
+ return result;
620
+ }
621
+
622
+ parseBalance (response) {
623
+ const outerResult = this.safeValue (response, 'result');
624
+ const firstResult = this.safeValue (outerResult, 0, {});
625
+ const innerResult = this.safeValue (firstResult, 'result');
626
+ const result = { 'info': response };
627
+ const assetsList = this.safeValue (innerResult, 'assets_list', []);
628
+ for (let i = 0; i < assetsList.length; i++) {
629
+ const balance = assetsList[i];
630
+ const currencyId = this.safeString (balance, 'coin_symbol');
631
+ const code = this.safeCurrencyCode (currencyId);
632
+ const account = this.account ();
633
+ account['free'] = this.safeString (balance, 'balance');
634
+ account['used'] = this.safeString (balance, 'freeze');
635
+ result[code] = account;
636
+ }
637
+ return this.safeBalance (result);
638
+ }
639
+
640
+ async fetchBalance (params = {}) {
641
+ await this.loadMarkets ();
642
+ const type = this.safeString (params, 'type', 'assets');
643
+ params = this.omit (params, 'type');
644
+ const request = {
645
+ 'cmd': 'transfer/' + type, // assets, mainAssets
646
+ 'body': this.extend ({
647
+ 'select': 1, // return full info
648
+ }, params),
649
+ };
650
+ const response = await this.privatePostTransfer (request);
651
+ //
652
+ // {
653
+ // "result":[
654
+ // {
655
+ // "result":{
656
+ // "total_btc":"0.00000298",
657
+ // "total_cny":"0.99",
658
+ // "total_usd":"0.16",
659
+ // "assets_list":[
660
+ // {"coin_symbol":"BTC","BTCValue":"0.00000252","CNYValue":"0.84","USDValue":"0.14","balance":"0.00000252","freeze":"0.00000000"},
661
+ // {"coin_symbol":"LTC","BTCValue":"0.00000023","CNYValue":"0.07","USDValue":"0.01","balance":"0.00006765","freeze":"0.00000000"},
662
+ // {"coin_symbol":"USDT","BTCValue":"0.00000023","CNYValue":"0.08","USDValue":"0.01","balance":"0.01252100","freeze":"0.00000000"}
663
+ // ]
664
+ // },
665
+ // "cmd":"transfer/assets"
666
+ // }
667
+ // ]
668
+ // }
669
+ //
670
+ return this.parseBalance (response);
671
+ }
672
+
673
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
674
+ await this.loadMarkets ();
675
+ if (limit === undefined) {
676
+ limit = 100;
677
+ }
678
+ const request = {
679
+ 'page': 1,
680
+ 'size': limit,
681
+ };
682
+ let currency = undefined;
683
+ if (code !== undefined) {
684
+ currency = this.currency (code);
685
+ request['symbol'] = currency['id'];
686
+ }
687
+ const response = await this.privatePostTransfer ({
688
+ 'cmd': 'transfer/transferInList',
689
+ 'body': this.extend (request, params),
690
+ });
691
+ //
692
+ // {
693
+ // "result":[
694
+ // {
695
+ // "result":{
696
+ // "count":2,
697
+ // "page":1,
698
+ // "items":[
699
+ // {
700
+ // "coin_symbol":"ETH", // token
701
+ // "to_address":"xxxxxxxxxxxxxxxxxxxxxxxxxx", // address
702
+ // "amount":"1.00000000", // amount
703
+ // "confirmCount":"15", // the acknowledgment number
704
+ // "createdAt":1540641511000,
705
+ // "status":2 // status, 1-deposit is in process,2-deposit finished,3-deposit failed
706
+ // },
707
+ // {
708
+ // "coin_symbol":"BIX",
709
+ // "to_address":"xxxxxxxxxxxxxxxxxxxxxxxxxx",
710
+ // "amount":"1.00000000",
711
+ // "confirmCount":"15",
712
+ // "createdAt":1540622460000,
713
+ // "status":2
714
+ // }
715
+ // ]
716
+ // },
717
+ // "cmd":"transfer/transferInList"
718
+ // }
719
+ // ]
720
+ // }
721
+ //
722
+ const outerResults = this.safeValue (response, 'result');
723
+ const firstResult = this.safeValue (outerResults, 0, {});
724
+ const innerResult = this.safeValue (firstResult, 'result', {});
725
+ const deposits = this.safeValue (innerResult, 'items', []);
726
+ for (let i = 0; i < deposits.length; i++) {
727
+ deposits[i]['type'] = 'deposit';
728
+ }
729
+ return this.parseTransactions (deposits, currency, since, limit);
730
+ }
731
+
732
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
733
+ await this.loadMarkets ();
734
+ if (limit === undefined) {
735
+ limit = 100;
736
+ }
737
+ const request = {
738
+ 'page': 1,
739
+ 'size': limit,
740
+ };
741
+ let currency = undefined;
742
+ if (code !== undefined) {
743
+ currency = this.currency (code);
744
+ request['symbol'] = currency['id'];
745
+ }
746
+ const response = await this.privatePostTransfer ({
747
+ 'cmd': 'transfer/transferOutList',
748
+ 'body': this.extend (request, params),
749
+ });
750
+ //
751
+ // {
752
+ // "result":[
753
+ // {
754
+ // "result":{
755
+ // "count":1,
756
+ // "page":1,
757
+ // "items":[
758
+ // {
759
+ // "id":612867,
760
+ // "coin_symbol":"ETH",
761
+ // "chain_type":"ETH",
762
+ // "to_address":"0xd41de7a88ab5fc59edc6669f54873576be95bff1",
763
+ // "tx_id":"0xc60950596227af3f27c3a1b5911ea1c79bae53bdce67274e48a0ce87a5ef2df8",
764
+ // "addr_remark":"binance",
765
+ // "amount":"2.34550946",
766
+ // "fee":"0.00600000",
767
+ // "createdAt":1561339330000,
768
+ // "memo":"",
769
+ // "status":3
770
+ // }
771
+ // ]
772
+ // },
773
+ // "cmd":"transfer/transferOutList"
774
+ // }
775
+ // ]
776
+ // }
777
+ //
778
+ const outerResults = this.safeValue (response, 'result');
779
+ const firstResult = this.safeValue (outerResults, 0, {});
780
+ const innerResult = this.safeValue (firstResult, 'result', {});
781
+ const withdrawals = this.safeValue (innerResult, 'items', []);
782
+ for (let i = 0; i < withdrawals.length; i++) {
783
+ withdrawals[i]['type'] = 'withdrawal';
784
+ }
785
+ return this.parseTransactions (withdrawals, currency, since, limit);
786
+ }
787
+
788
+ parseTransaction (transaction, currency = undefined) {
789
+ //
790
+ // fetchDeposits
791
+ //
792
+ // {
793
+ // 'id': 1023291,
794
+ // 'coin_symbol': 'ETH',
795
+ // 'to_address': '0x7263....',
796
+ // 'amount': '0.49170000',
797
+ // 'confirmCount': '16',
798
+ // 'createdAt': 1553123867000,
799
+ // 'status': 2
800
+ // }
801
+ //
802
+ // fetchWithdrawals
803
+ //
804
+ // {
805
+ // 'id': 521844,
806
+ // 'coin_symbol': 'ETH',
807
+ // 'to_address': '0xfd4e....',
808
+ // 'addr_remark': '',
809
+ // 'amount': '0.39452750',
810
+ // 'fee': '0.00600000',
811
+ // 'createdAt': 1553226906000,
812
+ // 'memo': '',
813
+ // 'status': 3
814
+ // }
815
+ //
816
+ // withdraw
817
+ //
818
+ // {
819
+ // "result": 228, // withdrawal id
820
+ // "cmd":"transfer/transferOut"
821
+ // }
822
+ //
823
+ const id = this.safeString2 (transaction, 'id', 'result');
824
+ const address = this.safeString (transaction, 'to_address');
825
+ const currencyId = this.safeString (transaction, 'coin_symbol');
826
+ const code = this.safeCurrencyCode (currencyId, currency);
827
+ const timestamp = this.safeString (transaction, 'createdAt');
828
+ let tag = this.safeString (transaction, 'addr_remark');
829
+ const type = this.safeString (transaction, 'type');
830
+ const status = this.parseTransactionStatusByType (this.safeString (transaction, 'status'), type);
831
+ const amount = this.safeNumber (transaction, 'amount');
832
+ let feeCost = this.safeNumber (transaction, 'fee');
833
+ if (type === 'deposit') {
834
+ feeCost = 0;
835
+ tag = undefined;
836
+ }
837
+ const fee = {
838
+ 'cost': feeCost,
839
+ 'currency': code,
840
+ };
841
+ return {
842
+ 'info': transaction,
843
+ 'id': id,
844
+ 'txid': undefined,
845
+ 'timestamp': timestamp,
846
+ 'datetime': this.iso8601 (timestamp),
847
+ 'network': undefined,
848
+ 'address': address,
849
+ 'addressTo': undefined,
850
+ 'addressFrom': undefined,
851
+ 'tag': tag,
852
+ 'tagTo': undefined,
853
+ 'tagFrom': undefined,
854
+ 'type': type,
855
+ 'amount': amount,
856
+ 'currency': code,
857
+ 'status': status,
858
+ 'updated': undefined,
859
+ 'fee': fee,
860
+ };
861
+ }
862
+
863
+ parseTransactionStatusByType (status, type = undefined) {
864
+ const statuses = {
865
+ 'deposit': {
866
+ '1': 'pending',
867
+ '2': 'ok',
868
+ },
869
+ 'withdrawal': {
870
+ '0': 'pending',
871
+ '3': 'ok',
872
+ },
873
+ };
874
+ return this.safeString (this.safeValue (statuses, type, {}), status, status);
875
+ }
876
+
877
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
878
+ await this.loadMarkets ();
879
+ const market = this.market (symbol);
880
+ const orderType = (type === 'limit') ? 2 : 1;
881
+ const orderSide = (side === 'buy') ? 1 : 2;
882
+ const request = {
883
+ 'cmd': 'orderpending/trade',
884
+ 'body': this.extend ({
885
+ 'pair': market['id'],
886
+ 'account_type': 0,
887
+ 'order_type': orderType,
888
+ 'order_side': orderSide,
889
+ 'pay_bix': 0,
890
+ 'amount': amount,
891
+ 'price': price,
892
+ }, params),
893
+ };
894
+ const response = await this.privatePostOrderpending (request);
895
+ //
896
+ // {
897
+ // "result":[
898
+ // {
899
+ // "result": "100055558128036", // order id
900
+ // "index": 12345, // random index, specific one in a batch
901
+ // "cmd":"orderpending/trade"
902
+ // }
903
+ // ]
904
+ // }
905
+ //
906
+ const outerResults = this.safeValue (response, 'result');
907
+ const firstResult = this.safeValue (outerResults, 0, {});
908
+ const id = this.safeValue (firstResult, 'result');
909
+ return {
910
+ 'info': response,
911
+ 'id': id,
912
+ };
913
+ }
914
+
915
+ async cancelOrder (id, symbol = undefined, params = {}) {
916
+ const request = {
917
+ 'cmd': 'orderpending/cancelTrade',
918
+ 'body': this.extend ({
919
+ 'orders_id': id,
920
+ }, params),
921
+ };
922
+ const response = await this.privatePostOrderpending (request);
923
+ //
924
+ // {
925
+ // "result":[
926
+ // {
927
+ // "result":"OK", // only indicates if the server received the cancelling request, and the cancelling result can be obtained from the order record
928
+ // "index": 12345, // random index, specific one in a batch
929
+ // "cmd":"orderpending/cancelTrade"
930
+ // }
931
+ // ]
932
+ // }
933
+ //
934
+ const outerResults = this.safeValue (response, 'result');
935
+ const firstResult = this.safeValue (outerResults, 0, {});
936
+ return firstResult;
937
+ }
938
+
939
+ async fetchOrder (id, symbol = undefined, params = {}) {
940
+ await this.loadMarkets ();
941
+ const request = {
942
+ 'cmd': 'orderpending/order',
943
+ 'body': this.extend ({
944
+ 'id': id.toString (),
945
+ 'account_type': 0, // 0 = spot account
946
+ }, params),
947
+ };
948
+ const response = await this.privatePostOrderpending (request);
949
+ //
950
+ // {
951
+ // "result":[
952
+ // {
953
+ // "result":{
954
+ // "id":"100055558128036",
955
+ // "createdAt": 1512756997000,
956
+ // "account_type":0,
957
+ // "coin_symbol":"LTC", // Trading Token
958
+ // "currency_symbol":"BTC", // Pricing Token
959
+ // "order_side":2, // Trading side 1-Buy, 2-Sell
960
+ // "order_type":2, // 2-limit order
961
+ // "price":"0.00900000", // order price
962
+ // "amount":"1.00000000", // order amount
963
+ // "money":"0.00900000", // currency amount (price * amount)
964
+ // "deal_amount":"0.00000000", // deal amount
965
+ // "deal_percent":"0.00%", // deal percentage
966
+ // "unexecuted":"0.00000000", // unexecuted amount
967
+ // "status":3 // Status, -1-fail, 0,1-to be dealt, 2-dealt partly, 3-dealt totally, 4- cancelled partly, 5-cancelled totally, 6-to be cancelled
968
+ // },
969
+ // "cmd":"orderpending/order"
970
+ // }
971
+ // ]
972
+ // }
973
+ //
974
+ const outerResults = this.safeValue (response, 'result');
975
+ const firstResult = this.safeValue (outerResults, 0, {});
976
+ const order = this.safeValue (firstResult, 'result');
977
+ if (this.isEmpty (order)) {
978
+ throw new OrderNotFound (this.id + ' order ' + id + ' not found');
979
+ }
980
+ return this.parseOrder (order);
981
+ }
982
+
983
+ parseOrder (order, market = undefined) {
984
+ let marketId = undefined;
985
+ const baseId = this.safeString (order, 'coin_symbol');
986
+ const quoteId = this.safeString (order, 'currency_symbol');
987
+ if ((baseId !== undefined) && (quoteId !== undefined)) {
988
+ marketId = baseId + '_' + quoteId;
989
+ }
990
+ market = this.safeMarket (marketId, market);
991
+ const rawType = this.safeString (order, 'order_type');
992
+ const type = (rawType === '1') ? 'market' : 'limit';
993
+ const timestamp = this.safeInteger (order, 'createdAt');
994
+ const price = this.safeString (order, 'price');
995
+ const average = this.safeString (order, 'deal_price');
996
+ const filled = this.safeString (order, 'deal_amount');
997
+ const amount = this.safeString (order, 'amount');
998
+ const cost = this.safeString2 (order, 'deal_money', 'money');
999
+ const rawSide = this.safeString (order, 'order_side');
1000
+ const side = (rawSide === '1') ? 'buy' : 'sell';
1001
+ const status = this.parseOrderStatus (this.safeString (order, 'status'));
1002
+ const id = this.safeString (order, 'id');
1003
+ const feeCost = this.safeString (order, 'fee');
1004
+ let fee = undefined;
1005
+ if (feeCost !== undefined) {
1006
+ fee = {
1007
+ 'cost': feeCost,
1008
+ 'currency': undefined,
1009
+ };
1010
+ }
1011
+ return this.safeOrder ({
1012
+ 'info': order,
1013
+ 'id': id,
1014
+ 'clientOrderId': undefined,
1015
+ 'timestamp': timestamp,
1016
+ 'datetime': this.iso8601 (timestamp),
1017
+ 'lastTradeTimestamp': undefined,
1018
+ 'symbol': market['symbol'],
1019
+ 'type': type,
1020
+ 'timeInForce': undefined,
1021
+ 'postOnly': undefined,
1022
+ 'side': side,
1023
+ 'price': price,
1024
+ 'stopPrice': undefined,
1025
+ 'amount': amount,
1026
+ 'cost': cost,
1027
+ 'average': average,
1028
+ 'filled': filled,
1029
+ 'remaining': undefined,
1030
+ 'status': status,
1031
+ 'fee': fee,
1032
+ 'trades': undefined,
1033
+ }, market);
1034
+ }
1035
+
1036
+ parseOrderStatus (status) {
1037
+ const statuses = {
1038
+ // original comments from bibox:
1039
+ '1': 'open', // pending
1040
+ '2': 'open', // part completed
1041
+ '3': 'closed', // completed
1042
+ '4': 'canceled', // part canceled
1043
+ '5': 'canceled', // canceled
1044
+ '6': 'canceled', // canceling
1045
+ };
1046
+ return this.safeString (statuses, status, status);
1047
+ }
1048
+
1049
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1050
+ await this.loadMarkets ();
1051
+ let market = undefined;
1052
+ let pair = undefined;
1053
+ if (symbol !== undefined) {
1054
+ market = this.market (symbol);
1055
+ pair = market['id'];
1056
+ }
1057
+ const size = limit ? limit : 200;
1058
+ const request = {
1059
+ 'cmd': 'orderpending/orderPendingList',
1060
+ 'body': this.extend ({
1061
+ 'pair': pair,
1062
+ 'account_type': 0, // 0 - regular, 1 - margin
1063
+ 'page': 1,
1064
+ 'size': size,
1065
+ }, params),
1066
+ };
1067
+ const response = await this.privatePostOrderpending (request);
1068
+ //
1069
+ // {
1070
+ // "result":[
1071
+ // {
1072
+ // "result":{
1073
+ // "count":1,
1074
+ // "page":1,
1075
+ // "items":[
1076
+ // {
1077
+ // "id":"100055558128036",
1078
+ // "createdAt": 1512756997000,
1079
+ // "account_type":0,
1080
+ // "coin_symbol":"LTC", // Trading Token
1081
+ // "currency_symbol":"BTC", // Pricing Token
1082
+ // "order_side":2, // Trading side 1-Buy, 2-Sell
1083
+ // "order_type":2, // 2-limit order
1084
+ // "price":"0.00900000", // order price
1085
+ // "amount":"1.00000000", // order amount
1086
+ // "money":"0.00900000", // currency amount (price * amount)
1087
+ // "deal_amount":"0.00000000", // deal amount
1088
+ // "deal_percent":"0.00%", // deal percentage
1089
+ // "unexecuted":"0.00000000", // unexecuted amount
1090
+ // "status":1 // Status,-1-fail, 0,1-to be dealt, 2-dealt partly, 3-dealt totally, 4- cancelled partly, 5-cancelled totally, 6-to be cancelled
1091
+ // }
1092
+ // ]
1093
+ // },
1094
+ // "cmd":"orderpending/orderPendingList"
1095
+ // }
1096
+ // ]
1097
+ // }
1098
+ //
1099
+ const outerResults = this.safeValue (response, 'result');
1100
+ const firstResult = this.safeValue (outerResults, 0, {});
1101
+ const innerResult = this.safeValue (firstResult, 'result', {});
1102
+ const orders = this.safeValue (innerResult, 'items', []);
1103
+ return this.parseOrders (orders, market, since, limit);
1104
+ }
1105
+
1106
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = 200, params = {}) {
1107
+ if (symbol === undefined) {
1108
+ throw new ArgumentsRequired (this.id + ' fetchClosedOrders() requires a `symbol` argument');
1109
+ }
1110
+ await this.loadMarkets ();
1111
+ const market = this.market (symbol);
1112
+ const request = {
1113
+ 'cmd': 'orderpending/pendingHistoryList',
1114
+ 'body': this.extend ({
1115
+ 'pair': market['id'],
1116
+ 'account_type': 0, // 0 - regular, 1 - margin
1117
+ 'page': 1,
1118
+ 'size': limit,
1119
+ }, params),
1120
+ };
1121
+ const response = await this.privatePostOrderpending (request);
1122
+ //
1123
+ // {
1124
+ // "result":[
1125
+ // {
1126
+ // "result":{
1127
+ // "count":1,
1128
+ // "page":1,
1129
+ // "items":[
1130
+ // {
1131
+ // "id":"100055558128036",
1132
+ // "createdAt": 1512756997000,
1133
+ // "account_type":0,
1134
+ // "coin_symbol":"LTC", // Trading Token
1135
+ // "currency_symbol":"BTC", // Pricing Token
1136
+ // "order_side":2, // Trading side 1-Buy, 2-Sell
1137
+ // "order_type":2, // 2-limit order
1138
+ // "price":"0.00900000", // order price
1139
+ // "amount":"1.00000000", // order amount
1140
+ // "money":"0.00900000", // currency amount (price * amount)
1141
+ // "deal_amount":"0.00000000", // deal amount
1142
+ // "deal_percent":"0.00%", // deal percentage
1143
+ // "unexecuted":"0.00000000", // unexecuted amount
1144
+ // "status":3 // Status,-1-fail, 0,1-to be dealt, 2-dealt partly, 3-dealt totally, 4- cancelled partly, 5-cancelled totally, 6-to be cancelled
1145
+ // }
1146
+ // ]
1147
+ // },
1148
+ // "cmd":"orderpending/pendingHistoryList"
1149
+ // }
1150
+ // ]
1151
+ // }
1152
+ //
1153
+ const outerResults = this.safeValue (response, 'result');
1154
+ const firstResult = this.safeValue (outerResults, 0, {});
1155
+ const innerResult = this.safeValue (firstResult, 'result', {});
1156
+ const orders = this.safeValue (innerResult, 'items', []);
1157
+ return this.parseOrders (orders, market, since, limit);
1158
+ }
1159
+
1160
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1161
+ if (symbol === undefined) {
1162
+ throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a `symbol` argument');
1163
+ }
1164
+ await this.loadMarkets ();
1165
+ const market = this.market (symbol);
1166
+ const size = limit ? limit : 200;
1167
+ const request = {
1168
+ 'cmd': 'orderpending/orderHistoryList',
1169
+ 'body': this.extend ({
1170
+ 'pair': market['id'],
1171
+ 'account_type': 0, // 0 - regular, 1 - margin
1172
+ 'page': 1,
1173
+ 'size': size,
1174
+ 'coin_symbol': market['baseId'],
1175
+ 'currency_symbol': market['quoteId'],
1176
+ }, params),
1177
+ };
1178
+ const response = await this.privatePostOrderpending (request);
1179
+ //
1180
+ // {
1181
+ // "result":[
1182
+ // {
1183
+ // "result":{
1184
+ // "count":1,
1185
+ // "page":1,
1186
+ // "items":[
1187
+ // {
1188
+ // "id":"100055558128033",
1189
+ // "createdAt": 1512756997000,
1190
+ // "account_type":0,
1191
+ // "coin_symbol":"LTC",
1192
+ // "currency_symbol":"BTC",
1193
+ // "order_side":2,
1194
+ // "order_type":2,
1195
+ // "price":"0.00886500",
1196
+ // "amount":"1.00000000",
1197
+ // "money":"0.00886500",
1198
+ // "fee":0
1199
+ // }
1200
+ // ]
1201
+ // },
1202
+ // "cmd":"orderpending/orderHistoryList"
1203
+ // }
1204
+ // ]
1205
+ // }
1206
+ //
1207
+ const outerResults = this.safeValue (response, 'result');
1208
+ const firstResult = this.safeValue (outerResults, 0, {});
1209
+ const innerResult = this.safeValue (firstResult, 'result', {});
1210
+ const trades = this.safeValue (innerResult, 'items', []);
1211
+ return this.parseTrades (trades, market, since, limit);
1212
+ }
1213
+
1214
+ async fetchDepositAddress (code, params = {}) {
1215
+ await this.loadMarkets ();
1216
+ const currency = this.currency (code);
1217
+ const request = {
1218
+ 'cmd': 'transfer/transferIn',
1219
+ 'body': this.extend ({
1220
+ 'coin_symbol': currency['id'],
1221
+ }, params),
1222
+ };
1223
+ const response = await this.privatePostTransfer (request);
1224
+ //
1225
+ // {
1226
+ // "result":[
1227
+ // {
1228
+ // "result":"3Jx6RZ9TNMsAoy9NUzBwZf68QBppDruSKW",
1229
+ // "cmd":"transfer/transferIn"
1230
+ // }
1231
+ // ]
1232
+ // }
1233
+ //
1234
+ // {
1235
+ // "result":[
1236
+ // {
1237
+ // "result":"{\"account\":\"PERSONALLY OMITTED\",\"memo\":\"PERSONALLY OMITTED\"}",
1238
+ // "cmd":"transfer/transferIn"
1239
+ // }
1240
+ // ]
1241
+ // }
1242
+ //
1243
+ const outerResults = this.safeValue (response, 'result');
1244
+ const firstResult = this.safeValue (outerResults, 0, {});
1245
+ const innerResult = this.safeValue (firstResult, 'result');
1246
+ let address = innerResult;
1247
+ let tag = undefined;
1248
+ if (this.isJsonEncodedObject (innerResult)) {
1249
+ const parsed = JSON.parse (innerResult);
1250
+ address = this.safeString (parsed, 'account');
1251
+ tag = this.safeString (parsed, 'memo');
1252
+ }
1253
+ return {
1254
+ 'currency': code,
1255
+ 'address': address,
1256
+ 'tag': tag,
1257
+ 'network': undefined,
1258
+ 'info': response,
1259
+ };
1260
+ }
1261
+
1262
+ async withdraw (code, amount, address, tag = undefined, params = {}) {
1263
+ [ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
1264
+ this.checkAddress (address);
1265
+ await this.loadMarkets ();
1266
+ const currency = this.currency (code);
1267
+ if (this.password === undefined) {
1268
+ if (!('trade_pwd' in params)) {
1269
+ throw new ExchangeError (this.id + ' withdraw() requires this.password set on the exchange instance or a trade_pwd parameter');
1270
+ }
1271
+ }
1272
+ if (!('totp_code' in params)) {
1273
+ throw new ExchangeError (this.id + ' withdraw() requires a totp_code parameter for 2FA authentication');
1274
+ }
1275
+ const request = {
1276
+ 'trade_pwd': this.password,
1277
+ 'coin_symbol': currency['id'],
1278
+ 'amount': amount,
1279
+ 'addr': address,
1280
+ };
1281
+ if (tag !== undefined) {
1282
+ request['address_remark'] = tag;
1283
+ }
1284
+ const response = await this.privatePostTransfer ({
1285
+ 'cmd': 'transfer/transferOut',
1286
+ 'body': this.extend (request, params),
1287
+ });
1288
+ //
1289
+ // {
1290
+ // "result":[
1291
+ // {
1292
+ // "result": 228, // withdrawal id
1293
+ // "cmd":"transfer/transferOut"
1294
+ // }
1295
+ // ]
1296
+ // }
1297
+ //
1298
+ const outerResults = this.safeValue (response, 'result');
1299
+ const firstResult = this.safeValue (outerResults, 0, {});
1300
+ return this.parseTransaction (firstResult, currency);
1301
+ }
1302
+
1303
+ async fetchFundingFees (codes = undefined, params = {}) {
1304
+ // by default it will try load withdrawal fees of all currencies (with separate requests)
1305
+ // however if you define codes = [ 'ETH', 'BTC' ] in args it will only load those
1306
+ await this.loadMarkets ();
1307
+ const withdrawFees = {};
1308
+ const info = {};
1309
+ if (codes === undefined) {
1310
+ codes = Object.keys (this.currencies);
1311
+ }
1312
+ for (let i = 0; i < codes.length; i++) {
1313
+ const code = codes[i];
1314
+ const currency = this.currency (code);
1315
+ const request = {
1316
+ 'cmd': 'transfer/coinConfig',
1317
+ 'body': this.extend ({
1318
+ 'coin_symbol': currency['id'],
1319
+ }, params),
1320
+ };
1321
+ const response = await this.privatePostTransfer (request);
1322
+ // {
1323
+ // "result":[
1324
+ // {
1325
+ // "result":[
1326
+ // {
1327
+ // "coin_symbol":"ETH",
1328
+ // "is_active":1,
1329
+ // "original_decimals":18,
1330
+ // "enable_deposit":1,
1331
+ // "enable_withdraw":1,
1332
+ // "withdraw_fee":0.008,
1333
+ // "withdraw_min":0.05,
1334
+ // "deposit_avg_spent":173700,
1335
+ // "withdraw_avg_spent":322600
1336
+ // }
1337
+ // ],
1338
+ // "cmd":"transfer/coinConfig"
1339
+ // }
1340
+ // ]
1341
+ // }
1342
+ //
1343
+ const outerResults = this.safeValue (response, 'result', []);
1344
+ const firstOuterResult = this.safeValue (outerResults, 0, {});
1345
+ const innerResults = this.safeValue (firstOuterResult, 'result', []);
1346
+ const firstInnerResult = this.safeValue (innerResults, 0, {});
1347
+ info[code] = firstInnerResult;
1348
+ withdrawFees[code] = this.safeNumber (firstInnerResult, 'withdraw_fee');
1349
+ }
1350
+ return {
1351
+ 'info': info,
1352
+ 'withdraw': withdrawFees,
1353
+ 'deposit': {},
1354
+ };
1355
+ }
1356
+
1357
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1358
+ let url = this.implodeHostname (this.urls['api']) + '/' + this.version + '/' + path;
1359
+ const cmds = this.json ([ params ]);
1360
+ if (api === 'public') {
1361
+ if (method !== 'GET') {
1362
+ body = { 'cmds': cmds };
1363
+ } else if (Object.keys (params).length) {
1364
+ url += '?' + this.urlencode (params);
1365
+ }
1366
+ } else if (api === 'v2private') {
1367
+ this.checkRequiredCredentials ();
1368
+ url = this.implodeHostname (this.urls['api']) + '/v2/' + path;
1369
+ const json_params = this.json (params);
1370
+ body = {
1371
+ 'body': json_params,
1372
+ 'apikey': this.apiKey,
1373
+ 'sign': this.hmac (this.encode (json_params), this.encode (this.secret), 'md5'),
1374
+ };
1375
+ } else {
1376
+ this.checkRequiredCredentials ();
1377
+ body = {
1378
+ 'cmds': cmds,
1379
+ 'apikey': this.apiKey,
1380
+ 'sign': this.hmac (this.encode (cmds), this.encode (this.secret), 'md5'),
1381
+ };
1382
+ }
1383
+ if (body !== undefined) {
1384
+ body = this.json (body, { 'convertArraysToObjects': true });
1385
+ }
1386
+ headers = { 'Content-Type': 'application/json' };
1387
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1388
+ }
1389
+
1390
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1391
+ if (response === undefined) {
1392
+ return;
1393
+ }
1394
+ if ('error' in response) {
1395
+ if ('code' in response['error']) {
1396
+ const code = this.safeString (response['error'], 'code');
1397
+ const feedback = this.id + ' ' + body;
1398
+ this.throwExactlyMatchedException (this.exceptions, code, feedback);
1399
+ throw new ExchangeError (feedback);
1400
+ }
1401
+ throw new ExchangeError (this.id + ' ' + body);
1402
+ }
1403
+ if (!('result' in response)) {
1404
+ throw new ExchangeError (this.id + ' ' + body);
1405
+ }
1406
+ }
1407
+ };