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
@@ -0,0 +1,1585 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { AccountSuspended, BadRequest, BadResponse, NetworkError, DDoSProtection, AuthenticationError, PermissionDenied, ExchangeError, InsufficientFunds, InvalidOrder, InvalidNonce, OrderNotFound, InvalidAddress, RateLimitExceeded, BadSymbol } = require ('./base/errors');
7
+
8
+ // ---------------------------------------------------------------------------
9
+
10
+ module.exports = class digifinex extends Exchange {
11
+ describe () {
12
+ return this.deepExtend (super.describe (), {
13
+ 'id': 'digifinex',
14
+ 'name': 'DigiFinex',
15
+ 'countries': [ 'SG' ],
16
+ 'version': 'v3',
17
+ 'rateLimit': 900, // 300 for posts
18
+ 'has': {
19
+ 'CORS': undefined,
20
+ 'spot': true,
21
+ 'margin': undefined, // has but unimplemented
22
+ 'swap': undefined, // has but unimplemented
23
+ 'future': undefined, // has but unimplemented
24
+ 'option': false,
25
+ 'cancelOrder': true,
26
+ 'cancelOrders': true,
27
+ 'createOrder': true,
28
+ 'fetchBalance': true,
29
+ 'fetchCurrencies': true,
30
+ 'fetchDepositAddress': true,
31
+ 'fetchDeposits': true,
32
+ 'fetchLedger': true,
33
+ 'fetchMarkets': true,
34
+ 'fetchMyTrades': true,
35
+ 'fetchOHLCV': true,
36
+ 'fetchOpenOrders': true,
37
+ 'fetchOrder': true,
38
+ 'fetchOrderBook': true,
39
+ 'fetchOrders': true,
40
+ 'fetchStatus': true,
41
+ 'fetchTicker': true,
42
+ 'fetchTickers': true,
43
+ 'fetchTime': true,
44
+ 'fetchTrades': true,
45
+ 'fetchTradingFee': false,
46
+ 'fetchTradingFees': false,
47
+ 'fetchWithdrawals': true,
48
+ 'transfer': true,
49
+ 'withdraw': true,
50
+ },
51
+ 'timeframes': {
52
+ '1m': '1',
53
+ '5m': '5',
54
+ '15m': '15',
55
+ '30m': '30',
56
+ '1h': '60',
57
+ '4h': '240',
58
+ '12h': '720',
59
+ '1d': '1D',
60
+ '1w': '1W',
61
+ },
62
+ 'urls': {
63
+ 'logo': 'https://user-images.githubusercontent.com/51840849/87443315-01283a00-c5fe-11ea-8628-c2a0feaf07ac.jpg',
64
+ 'api': 'https://openapi.digifinex.com',
65
+ 'www': 'https://www.digifinex.com',
66
+ 'doc': [
67
+ 'https://docs.digifinex.com',
68
+ ],
69
+ 'fees': 'https://digifinex.zendesk.com/hc/en-us/articles/360000328422-Fee-Structure-on-DigiFinex',
70
+ 'referral': 'https://www.digifinex.com/en-ww/from/DhOzBg?channelCode=ljaUPp',
71
+ },
72
+ 'api': {
73
+ 'public': {
74
+ 'get': [
75
+ '{market}/symbols',
76
+ 'kline',
77
+ 'margin/currencies',
78
+ 'margin/symbols',
79
+ 'markets',
80
+ 'order_book',
81
+ 'ping',
82
+ 'spot/symbols',
83
+ 'time',
84
+ 'trades',
85
+ 'trades/symbols',
86
+ 'ticker',
87
+ 'currencies',
88
+ ],
89
+ },
90
+ 'private': {
91
+ 'get': [
92
+ '{market}/financelog',
93
+ '{market}/mytrades',
94
+ '{market}/order',
95
+ '{market}/order/detail',
96
+ '{market}/order/current',
97
+ '{market}/order/history',
98
+ 'margin/assets',
99
+ 'margin/financelog',
100
+ 'margin/mytrades',
101
+ 'margin/order',
102
+ 'margin/order/current',
103
+ 'margin/order/history',
104
+ 'margin/positions',
105
+ 'otc/financelog',
106
+ 'spot/assets',
107
+ 'spot/financelog',
108
+ 'spot/mytrades',
109
+ 'spot/order',
110
+ 'spot/order/current',
111
+ 'spot/order/history',
112
+ 'deposit/address',
113
+ 'deposit/history',
114
+ 'withdraw/history',
115
+ ],
116
+ 'post': [
117
+ '{market}/order/cancel',
118
+ '{market}/order/new',
119
+ '{market}/order/batch_new',
120
+ 'margin/order/cancel',
121
+ 'margin/order/new',
122
+ 'margin/position/close',
123
+ 'spot/order/cancel',
124
+ 'spot/order/new',
125
+ 'transfer',
126
+ 'withdraw/new',
127
+ 'withdraw/cancel',
128
+ ],
129
+ },
130
+ },
131
+ 'fees': {
132
+ 'trading': {
133
+ 'tierBased': true,
134
+ 'percentage': true,
135
+ 'maker': this.parseNumber ('0.002'),
136
+ 'taker': this.parseNumber ('0.002'),
137
+ },
138
+ },
139
+ 'exceptions': {
140
+ 'exact': {
141
+ '10001': [ BadRequest, "Wrong request method, please check it's a GET ot POST request" ],
142
+ '10002': [ AuthenticationError, 'Invalid ApiKey' ],
143
+ '10003': [ AuthenticationError, "Sign doesn't match" ],
144
+ '10004': [ BadRequest, 'Illegal request parameters' ],
145
+ '10005': [ DDoSProtection, 'Request frequency exceeds the limit' ],
146
+ '10006': [ PermissionDenied, 'Unauthorized to execute this request' ],
147
+ '10007': [ PermissionDenied, 'IP address Unauthorized' ],
148
+ '10008': [ InvalidNonce, 'Timestamp for this request is invalid, timestamp must within 1 minute' ],
149
+ '10009': [ NetworkError, 'Unexist endpoint, please check endpoint URL' ],
150
+ '10011': [ AccountSuspended, 'ApiKey expired. Please go to client side to re-create an ApiKey' ],
151
+ '20001': [ PermissionDenied, 'Trade is not open for this trading pair' ],
152
+ '20002': [ PermissionDenied, 'Trade of this trading pair is suspended' ],
153
+ '20003': [ InvalidOrder, 'Invalid price or amount' ],
154
+ '20007': [ InvalidOrder, 'Price precision error' ],
155
+ '20008': [ InvalidOrder, 'Amount precision error' ],
156
+ '20009': [ InvalidOrder, 'Amount is less than the minimum requirement' ],
157
+ '20010': [ InvalidOrder, 'Cash Amount is less than the minimum requirement' ],
158
+ '20011': [ InsufficientFunds, 'Insufficient balance' ],
159
+ '20012': [ BadRequest, 'Invalid trade type, valid value: buy/sell)' ],
160
+ '20013': [ InvalidOrder, 'No order info found' ],
161
+ '20014': [ BadRequest, 'Invalid date, Valid format: 2018-07-25)' ],
162
+ '20015': [ BadRequest, 'Date exceeds the limit' ],
163
+ '20018': [ PermissionDenied, 'Your trading rights have been banned by the system' ],
164
+ '20019': [ BadSymbol, 'Wrong trading pair symbol. Correct format:"usdt_btc". Quote asset is in the front' ],
165
+ '20020': [ DDoSProtection, "You have violated the API operation trading rules and temporarily forbid trading. At present, we have certain restrictions on the user's transaction rate and withdrawal rate." ],
166
+ '50000': [ ExchangeError, 'Exception error' ],
167
+ '20021': [ BadRequest, 'Invalid currency' ],
168
+ '20022': [ BadRequest, 'The ending timestamp must be larger than the starting timestamp' ],
169
+ '20023': [ BadRequest, 'Invalid transfer type' ],
170
+ '20024': [ BadRequest, 'Invalid amount' ],
171
+ '20025': [ BadRequest, 'This currency is not transferable at the moment' ],
172
+ '20026': [ InsufficientFunds, 'Transfer amount exceed your balance' ],
173
+ '20027': [ PermissionDenied, 'Abnormal account status' ],
174
+ '20028': [ PermissionDenied, 'Blacklist for transfer' ],
175
+ '20029': [ PermissionDenied, 'Transfer amount exceed your daily limit' ],
176
+ '20030': [ BadRequest, 'You have no position on this trading pair' ],
177
+ '20032': [ PermissionDenied, 'Withdrawal limited' ],
178
+ '20033': [ BadRequest, 'Wrong Withdrawal ID' ],
179
+ '20034': [ PermissionDenied, 'Withdrawal service of this crypto has been closed' ],
180
+ '20035': [ PermissionDenied, 'Withdrawal limit' ],
181
+ '20036': [ ExchangeError, 'Withdrawal cancellation failed' ],
182
+ '20037': [ InvalidAddress, 'The withdrawal address, Tag or chain type is not included in the withdrawal management list' ],
183
+ '20038': [ InvalidAddress, 'The withdrawal address is not on the white list' ],
184
+ '20039': [ ExchangeError, "Can't be canceled in current status" ],
185
+ '20040': [ RateLimitExceeded, 'Withdraw too frequently; limitation: 3 times a minute, 100 times a day' ],
186
+ '20041': [ PermissionDenied, 'Beyond the daily withdrawal limit' ],
187
+ '20042': [ BadSymbol, 'Current trading pair does not support API trading' ],
188
+ },
189
+ 'broad': {
190
+ },
191
+ },
192
+ 'options': {
193
+ 'defaultType': 'spot',
194
+ 'types': [ 'spot', 'margin', 'otc' ],
195
+ 'accountsByType': {
196
+ 'spot': '1',
197
+ 'margin': '2',
198
+ 'OTC': '3',
199
+ },
200
+ },
201
+ 'commonCurrencies': {
202
+ 'BHT': 'Black House Test',
203
+ 'EPS': 'Epanus',
204
+ 'FREE': 'FreeRossDAO',
205
+ 'MBN': 'Mobilian Coin',
206
+ 'TEL': 'TEL666',
207
+ },
208
+ });
209
+ }
210
+
211
+ async fetchCurrencies (params = {}) {
212
+ const response = await this.publicGetCurrencies (params);
213
+ //
214
+ // {
215
+ // "data":[
216
+ // {
217
+ // "deposit_status":1,
218
+ // "min_deposit_amount":10,
219
+ // "withdraw_fee_rate":0,
220
+ // "min_withdraw_amount":10,
221
+ // "min_withdraw_fee":5,
222
+ // "currency":"USDT",
223
+ // "withdraw_status":0,
224
+ // "chain":"OMNI"
225
+ // },
226
+ // {
227
+ // "deposit_status":1,
228
+ // "min_deposit_amount":10,
229
+ // "withdraw_fee_rate":0,
230
+ // "min_withdraw_amount":10,
231
+ // "min_withdraw_fee":3,
232
+ // "currency":"USDT",
233
+ // "withdraw_status":1,
234
+ // "chain":"ERC20"
235
+ // },
236
+ // {
237
+ // "deposit_status":0,
238
+ // "min_deposit_amount":0,
239
+ // "withdraw_fee_rate":0,
240
+ // "min_withdraw_amount":0,
241
+ // "min_withdraw_fee":0,
242
+ // "currency":"DGF13",
243
+ // "withdraw_status":0,
244
+ // "chain":""
245
+ // },
246
+ // ],
247
+ // "code":200
248
+ // }
249
+ //
250
+ const data = this.safeValue (response, 'data', []);
251
+ const result = {};
252
+ for (let i = 0; i < data.length; i++) {
253
+ const currency = data[i];
254
+ const id = this.safeString (currency, 'currency');
255
+ const code = this.safeCurrencyCode (id);
256
+ const depositStatus = this.safeInteger (currency, 'deposit_status', 1);
257
+ const withdrawStatus = this.safeInteger (currency, 'withdraw_status', 1);
258
+ const deposit = depositStatus > 0;
259
+ const withdraw = withdrawStatus > 0;
260
+ const active = deposit && withdraw;
261
+ const fee = this.safeNumber (currency, 'withdraw_fee_rate');
262
+ if (code in result) {
263
+ if (Array.isArray (result[code]['info'])) {
264
+ result[code]['info'].push (currency);
265
+ } else {
266
+ result[code]['info'] = [ result[code]['info'], currency ];
267
+ }
268
+ } else {
269
+ result[code] = {
270
+ 'id': id,
271
+ 'code': code,
272
+ 'info': currency,
273
+ 'type': undefined,
274
+ 'name': undefined,
275
+ 'active': active,
276
+ 'deposit': deposit,
277
+ 'withdraw': withdraw,
278
+ 'fee': fee,
279
+ 'precision': 8, // todo fix hardcoded value
280
+ 'limits': {
281
+ 'amount': {
282
+ 'min': undefined,
283
+ 'max': undefined,
284
+ },
285
+ 'withdraw': {
286
+ 'min': this.safeNumber (currency, 'min_withdraw_amount'),
287
+ 'max': undefined,
288
+ },
289
+ },
290
+ };
291
+ }
292
+ }
293
+ return result;
294
+ }
295
+
296
+ async fetchMarkets (params = {}) {
297
+ const options = this.safeValue (this.options, 'fetchMarkets', {});
298
+ const method = this.safeString (options, 'method', 'fetch_markets_v2');
299
+ return await this[method] (params);
300
+ }
301
+
302
+ async fetchMarketsV2 (params = {}) {
303
+ const response = await this.publicGetTradesSymbols (params);
304
+ //
305
+ // {
306
+ // "symbol_list":[
307
+ // {
308
+ // "order_types":["LIMIT","MARKET"],
309
+ // "quote_asset":"USDT",
310
+ // "minimum_value":2,
311
+ // "amount_precision":4,
312
+ // "status":"TRADING",
313
+ // "minimum_amount":0.0001,
314
+ // "symbol":"BTC_USDT",
315
+ // "is_allow":1,
316
+ // "zone":"MAIN",
317
+ // "base_asset":"BTC",
318
+ // "price_precision":2
319
+ // }
320
+ // ],
321
+ // "code":0
322
+ // }
323
+ //
324
+ const markets = this.safeValue (response, 'symbol_list', []);
325
+ const result = [];
326
+ for (let i = 0; i < markets.length; i++) {
327
+ const market = markets[i];
328
+ const id = this.safeString (market, 'symbol');
329
+ const baseId = this.safeString (market, 'base_asset');
330
+ const quoteId = this.safeString (market, 'quote_asset');
331
+ const base = this.safeCurrencyCode (baseId);
332
+ const quote = this.safeCurrencyCode (quoteId);
333
+ //
334
+ // The status is documented in the exchange API docs as follows:
335
+ // TRADING, HALT (delisted), BREAK (trading paused)
336
+ // https://docs.digifinex.vip/en-ww/v3/#/public/spot/symbols
337
+ // However, all spot markets actually have status === 'HALT'
338
+ // despite that they appear to be active on the exchange website.
339
+ // Apparently, we can't trust this status.
340
+ // const status = this.safeString (market, 'status');
341
+ // const active = (status === 'TRADING');
342
+ //
343
+ const isAllowed = this.safeInteger (market, 'is_allow', 1);
344
+ result.push ({
345
+ 'id': id,
346
+ 'symbol': base + '/' + quote,
347
+ 'base': base,
348
+ 'quote': quote,
349
+ 'settle': undefined,
350
+ 'baseId': baseId,
351
+ 'quoteId': quoteId,
352
+ 'settleId': undefined,
353
+ 'type': 'spot',
354
+ 'spot': true,
355
+ 'margin': undefined,
356
+ 'swap': false,
357
+ 'future': false,
358
+ 'option': false,
359
+ 'active': isAllowed ? true : false,
360
+ 'contract': false,
361
+ 'linear': undefined,
362
+ 'inverse': undefined,
363
+ 'contractSize': undefined,
364
+ 'expiry': undefined,
365
+ 'expiryDatetime': undefined,
366
+ 'strike': undefined,
367
+ 'optionType': undefined,
368
+ 'precision': {
369
+ 'amount': this.safeInteger (market, 'amount_precision'),
370
+ 'price': this.safeInteger (market, 'price_precision'),
371
+ },
372
+ 'limits': {
373
+ 'leverage': {
374
+ 'min': undefined,
375
+ 'max': undefined,
376
+ },
377
+ 'amount': {
378
+ 'min': this.safeNumber (market, 'minimum_amount'),
379
+ 'max': undefined,
380
+ },
381
+ 'price': {
382
+ 'min': undefined,
383
+ 'max': undefined,
384
+ },
385
+ 'cost': {
386
+ 'min': this.safeNumber (market, 'minimum_value'),
387
+ 'max': undefined,
388
+ },
389
+ },
390
+ 'info': market,
391
+ });
392
+ }
393
+ return result;
394
+ }
395
+
396
+ async fetchMarketsV1 (params = {}) {
397
+ const response = await this.publicGetMarkets (params);
398
+ //
399
+ // {
400
+ // "data": [
401
+ // {
402
+ // "volume_precision":4,
403
+ // "price_precision":2,
404
+ // "market":"btc_usdt",
405
+ // "min_amount":2,
406
+ // "min_volume":0.0001
407
+ // },
408
+ // ],
409
+ // "date":1564507456,
410
+ // "code":0
411
+ // }
412
+ //
413
+ const markets = this.safeValue (response, 'data', []);
414
+ const result = [];
415
+ for (let i = 0; i < markets.length; i++) {
416
+ const market = markets[i];
417
+ const id = this.safeString (market, 'market');
418
+ const [ baseId, quoteId ] = id.split ('_');
419
+ const base = this.safeCurrencyCode (baseId);
420
+ const quote = this.safeCurrencyCode (quoteId);
421
+ result.push ({
422
+ 'id': id,
423
+ 'symbol': base + '/' + quote,
424
+ 'base': base,
425
+ 'quote': quote,
426
+ 'settle': undefined,
427
+ 'baseId': baseId,
428
+ 'quoteId': quoteId,
429
+ 'settleId': undefined,
430
+ 'type': 'spot',
431
+ 'spot': true,
432
+ 'margin': undefined,
433
+ 'swap': false,
434
+ 'future': false,
435
+ 'option': false,
436
+ 'active': undefined,
437
+ 'contract': false,
438
+ 'linear': undefined,
439
+ 'inverse': undefined,
440
+ 'contractSize': undefined,
441
+ 'expiry': undefined,
442
+ 'expiryDatetime': undefined,
443
+ 'strike': undefined,
444
+ 'optionType': undefined,
445
+ 'precision': {
446
+ 'price': this.safeInteger (market, 'price_precision'),
447
+ 'amount': this.safeInteger (market, 'volume_precision'),
448
+ },
449
+ 'limits': {
450
+ 'leverage': {
451
+ 'min': undefined,
452
+ 'max': undefined,
453
+ },
454
+ 'amount': {
455
+ 'min': this.safeNumber (market, 'min_volume'),
456
+ 'max': undefined,
457
+ },
458
+ 'price': {
459
+ 'min': undefined,
460
+ 'max': undefined,
461
+ },
462
+ 'cost': {
463
+ 'min': this.safeNumber (market, 'min_amount'),
464
+ 'max': undefined,
465
+ },
466
+ },
467
+ 'info': market,
468
+ });
469
+ }
470
+ return result;
471
+ }
472
+
473
+ parseBalance (response) {
474
+ const balances = this.safeValue (response, 'list', []);
475
+ const result = { 'info': response };
476
+ for (let i = 0; i < balances.length; i++) {
477
+ const balance = balances[i];
478
+ const currencyId = this.safeString (balance, 'currency');
479
+ const code = this.safeCurrencyCode (currencyId);
480
+ const account = this.account ();
481
+ account['used'] = this.safeString (balance, 'frozen');
482
+ account['free'] = this.safeString (balance, 'free');
483
+ account['total'] = this.safeString (balance, 'total');
484
+ result[code] = account;
485
+ }
486
+ return this.safeBalance (result);
487
+ }
488
+
489
+ async fetchBalance (params = {}) {
490
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
491
+ const type = this.safeString (params, 'type', defaultType);
492
+ params = this.omit (params, 'type');
493
+ const method = 'privateGet' + this.capitalize (type) + 'Assets';
494
+ const response = await this[method] (params);
495
+ //
496
+ // {
497
+ // "code": 0,
498
+ // "list": [
499
+ // {
500
+ // "currency": "BTC",
501
+ // "free": 4723846.89208129,
502
+ // "total": 0
503
+ // }
504
+ // ]
505
+ // }
506
+ return this.parseBalance (response);
507
+ }
508
+
509
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
510
+ await this.loadMarkets ();
511
+ const market = this.market (symbol);
512
+ const request = {
513
+ 'symbol': market['id'],
514
+ };
515
+ if (limit !== undefined) {
516
+ request['limit'] = limit; // default 10, max 150
517
+ }
518
+ const response = await this.publicGetOrderBook (this.extend (request, params));
519
+ //
520
+ // {
521
+ // "bids": [
522
+ // [9605.77,0.0016],
523
+ // [9605.46,0.0003],
524
+ // [9602.04,0.0127],
525
+ // ],
526
+ // "asks": [
527
+ // [9627.22,0.025803],
528
+ // [9627.12,0.168543],
529
+ // [9626.52,0.0011529],
530
+ // ],
531
+ // "date":1564509499,
532
+ // "code":0
533
+ // }
534
+ //
535
+ const timestamp = this.safeTimestamp (response, 'date');
536
+ return this.parseOrderBook (response, symbol, timestamp);
537
+ }
538
+
539
+ async fetchTickers (symbols = undefined, params = {}) {
540
+ await this.loadMarkets ();
541
+ const response = await this.publicGetTicker (params);
542
+ //
543
+ // {
544
+ // "ticker": [{
545
+ // "vol": 40717.4461,
546
+ // "change": -1.91,
547
+ // "base_vol": 392447999.65374,
548
+ // "sell": 9592.23,
549
+ // "last": 9592.22,
550
+ // "symbol": "btc_usdt",
551
+ // "low": 9476.24,
552
+ // "buy": 9592.03,
553
+ // "high": 9793.87
554
+ // }],
555
+ // "date": 1589874294,
556
+ // "code": 0
557
+ // }
558
+ //
559
+ const result = {};
560
+ const tickers = this.safeValue (response, 'ticker', []);
561
+ const date = this.safeInteger (response, 'date');
562
+ for (let i = 0; i < tickers.length; i++) {
563
+ const rawTicker = this.extend ({
564
+ 'date': date,
565
+ }, tickers[i]);
566
+ const ticker = this.parseTicker (rawTicker);
567
+ const symbol = ticker['symbol'];
568
+ result[symbol] = ticker;
569
+ }
570
+ return this.filterByArray (result, 'symbol', symbols);
571
+ }
572
+
573
+ async fetchTicker (symbol, params = {}) {
574
+ await this.loadMarkets ();
575
+ const market = this.market (symbol);
576
+ const request = {
577
+ 'symbol': market['id'],
578
+ };
579
+ const response = await this.publicGetTicker (this.extend (request, params));
580
+ //
581
+ // {
582
+ // "ticker": [{
583
+ // "vol": 40717.4461,
584
+ // "change": -1.91,
585
+ // "base_vol": 392447999.65374,
586
+ // "sell": 9592.23,
587
+ // "last": 9592.22,
588
+ // "symbol": "btc_usdt",
589
+ // "low": 9476.24,
590
+ // "buy": 9592.03,
591
+ // "high": 9793.87
592
+ // }],
593
+ // "date": 1589874294,
594
+ // "code": 0
595
+ // }
596
+ //
597
+ const date = this.safeInteger (response, 'date');
598
+ const tickers = this.safeValue (response, 'ticker', []);
599
+ const firstTicker = this.safeValue (tickers, 0, {});
600
+ const result = this.extend ({ 'date': date }, firstTicker);
601
+ return this.parseTicker (result, market);
602
+ }
603
+
604
+ parseTicker (ticker, market = undefined) {
605
+ //
606
+ // fetchTicker, fetchTickers
607
+ //
608
+ // {
609
+ // "last":0.021957,
610
+ // "symbol": "btc_usdt",
611
+ // "base_vol":2249.3521732227,
612
+ // "change":-0.6,
613
+ // "vol":102443.5111,
614
+ // "sell":0.021978,
615
+ // "low":0.021791,
616
+ // "buy":0.021946,
617
+ // "high":0.022266,
618
+ // "date"1564518452, // injected from fetchTicker/fetchTickers
619
+ // }
620
+ //
621
+ const marketId = this.safeStringUpper (ticker, 'symbol');
622
+ const symbol = this.safeSymbol (marketId, market, '_');
623
+ const timestamp = this.safeTimestamp (ticker, 'date');
624
+ const last = this.safeString (ticker, 'last');
625
+ const percentage = this.safeString (ticker, 'change');
626
+ return this.safeTicker ({
627
+ 'symbol': symbol,
628
+ 'timestamp': timestamp,
629
+ 'datetime': this.iso8601 (timestamp),
630
+ 'high': this.safeString (ticker, 'high'),
631
+ 'low': this.safeString (ticker, 'low'),
632
+ 'bid': this.safeString (ticker, 'buy'),
633
+ 'bidVolume': undefined,
634
+ 'ask': this.safeString (ticker, 'sell'),
635
+ 'askVolume': undefined,
636
+ 'vwap': undefined,
637
+ 'open': undefined,
638
+ 'close': last,
639
+ 'last': last,
640
+ 'previousClose': undefined,
641
+ 'change': undefined,
642
+ 'percentage': percentage,
643
+ 'average': undefined,
644
+ 'baseVolume': this.safeString (ticker, 'vol'),
645
+ 'quoteVolume': this.safeString (ticker, 'base_vol'),
646
+ 'info': ticker,
647
+ }, market, false);
648
+ }
649
+
650
+ parseTrade (trade, market = undefined) {
651
+ //
652
+ // fetchTrades (public)
653
+ //
654
+ // {
655
+ // "date":1564520003,
656
+ // "id":1596149203,
657
+ // "amount":0.7073,
658
+ // "type":"buy",
659
+ // "price":0.02193,
660
+ // }
661
+ //
662
+ // fetchMyTrades (private)
663
+ //
664
+ // {
665
+ // "symbol": "BTC_USDT",
666
+ // "order_id": "6707cbdcda0edfaa7f4ab509e4cbf966",
667
+ // "id": 28457,
668
+ // "price": 0.1,
669
+ // "amount": 0,
670
+ // "fee": 0.096,
671
+ // "fee_currency": "USDT",
672
+ // "timestamp": 1499865549,
673
+ // "side": "buy", // or "side": "sell_market"
674
+ // "is_maker": true
675
+ // }
676
+ //
677
+ const id = this.safeString (trade, 'id');
678
+ const orderId = this.safeString (trade, 'order_id');
679
+ const timestamp = this.safeTimestamp2 (trade, 'date', 'timestamp');
680
+ let side = this.safeString2 (trade, 'type', 'side');
681
+ const parts = side.split ('_');
682
+ side = this.safeString (parts, 0);
683
+ const type = this.safeString (parts, 1);
684
+ const priceString = this.safeString (trade, 'price');
685
+ const amountString = this.safeString (trade, 'amount');
686
+ const marketId = this.safeString (trade, 'symbol');
687
+ const symbol = this.safeSymbol (marketId, market, '_');
688
+ const takerOrMaker = this.safeValue (trade, 'is_maker');
689
+ const feeCostString = this.safeString (trade, 'fee');
690
+ let fee = undefined;
691
+ if (feeCostString !== undefined) {
692
+ const feeCurrencyId = this.safeString (trade, 'fee_currency');
693
+ const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
694
+ fee = {
695
+ 'cost': feeCostString,
696
+ 'currency': feeCurrencyCode,
697
+ };
698
+ }
699
+ return this.safeTrade ({
700
+ 'id': id,
701
+ 'info': trade,
702
+ 'timestamp': timestamp,
703
+ 'datetime': this.iso8601 (timestamp),
704
+ 'symbol': symbol,
705
+ 'type': type,
706
+ 'order': orderId,
707
+ 'side': side,
708
+ 'price': priceString,
709
+ 'amount': amountString,
710
+ 'cost': undefined,
711
+ 'takerOrMaker': takerOrMaker,
712
+ 'fee': fee,
713
+ }, market);
714
+ }
715
+
716
+ async fetchTime (params = {}) {
717
+ const response = await this.publicGetTime (params);
718
+ //
719
+ // {
720
+ // "server_time": 1589873762,
721
+ // "code": 0
722
+ // }
723
+ //
724
+ return this.safeTimestamp (response, 'server_time');
725
+ }
726
+
727
+ async fetchStatus (params = {}) {
728
+ const response = await this.publicGetPing (params);
729
+ //
730
+ // {
731
+ // "msg": "pong",
732
+ // "code": 0
733
+ // }
734
+ //
735
+ const code = this.safeInteger (response, 'code');
736
+ const status = (code === 0) ? 'ok' : 'maintenance';
737
+ return {
738
+ 'status': status,
739
+ 'updated': this.milliseconds (),
740
+ 'eta': undefined,
741
+ 'url': undefined,
742
+ 'info': response,
743
+ };
744
+ }
745
+
746
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
747
+ await this.loadMarkets ();
748
+ const market = this.market (symbol);
749
+ const request = {
750
+ 'symbol': market['id'],
751
+ };
752
+ if (limit !== undefined) {
753
+ request['limit'] = limit; // default 100, max 500
754
+ }
755
+ const response = await this.publicGetTrades (this.extend (request, params));
756
+ //
757
+ // {
758
+ // "data":[
759
+ // {
760
+ // "date":1564520003,
761
+ // "id":1596149203,
762
+ // "amount":0.7073,
763
+ // "type":"buy",
764
+ // "price":0.02193,
765
+ // },
766
+ // {
767
+ // "date":1564520002,
768
+ // "id":1596149165,
769
+ // "amount":0.3232,
770
+ // "type":"sell",
771
+ // "price":0.021927,
772
+ // },
773
+ // ],
774
+ // "code": 0,
775
+ // "date": 1564520003,
776
+ // }
777
+ //
778
+ const data = this.safeValue (response, 'data', []);
779
+ return this.parseTrades (data, market, since, limit);
780
+ }
781
+
782
+ parseOHLCV (ohlcv, market = undefined) {
783
+ //
784
+ // [
785
+ // 1556712900,
786
+ // 2205.899,
787
+ // 0.029967,
788
+ // 0.02997,
789
+ // 0.029871,
790
+ // 0.029927
791
+ // ]
792
+ //
793
+ return [
794
+ this.safeTimestamp (ohlcv, 0),
795
+ this.safeNumber (ohlcv, 5), // open
796
+ this.safeNumber (ohlcv, 3), // high
797
+ this.safeNumber (ohlcv, 4), // low
798
+ this.safeNumber (ohlcv, 2), // close
799
+ this.safeNumber (ohlcv, 1), // volume
800
+ ];
801
+ }
802
+
803
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
804
+ await this.loadMarkets ();
805
+ const market = this.market (symbol);
806
+ const request = {
807
+ 'symbol': market['id'],
808
+ 'period': this.timeframes[timeframe],
809
+ // 'start_time': 1564520003, // starting timestamp, 200 candles before end_time by default
810
+ // 'end_time': 1564520003, // ending timestamp, current timestamp by default
811
+ };
812
+ if (since !== undefined) {
813
+ const startTime = parseInt (since / 1000);
814
+ request['start_time'] = startTime;
815
+ if (limit !== undefined) {
816
+ const duration = this.parseTimeframe (timeframe);
817
+ request['end_time'] = this.sum (startTime, limit * duration);
818
+ }
819
+ } else if (limit !== undefined) {
820
+ const endTime = this.seconds ();
821
+ const duration = this.parseTimeframe (timeframe);
822
+ request['startTime'] = this.sum (endTime, -limit * duration);
823
+ }
824
+ const response = await this.publicGetKline (this.extend (request, params));
825
+ //
826
+ // {
827
+ // "code":0,
828
+ // "data":[
829
+ // [1556712900,2205.899,0.029967,0.02997,0.029871,0.029927],
830
+ // [1556713800,1912.9174,0.029992,0.030014,0.029955,0.02996],
831
+ // [1556714700,1556.4795,0.029974,0.030019,0.029969,0.02999],
832
+ // ]
833
+ // }
834
+ //
835
+ const data = this.safeValue (response, 'data', []);
836
+ return this.parseOHLCVs (data, market, timeframe, since, limit);
837
+ }
838
+
839
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
840
+ await this.loadMarkets ();
841
+ const market = this.market (symbol);
842
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
843
+ const orderType = this.safeString (params, 'type', defaultType);
844
+ params = this.omit (params, 'type');
845
+ const request = {
846
+ 'market': orderType,
847
+ 'symbol': market['id'],
848
+ 'amount': this.amountToPrecision (symbol, amount),
849
+ // 'post_only': 0, // 0 by default, if set to 1 the order will be canceled if it can be executed immediately, making sure there will be no market taking
850
+ };
851
+ let suffix = '';
852
+ if (type === 'market') {
853
+ suffix = '_market';
854
+ } else {
855
+ request['price'] = this.priceToPrecision (symbol, price);
856
+ }
857
+ request['type'] = side + suffix;
858
+ const response = await this.privatePostMarketOrderNew (this.extend (request, params));
859
+ //
860
+ // {
861
+ // "code": 0,
862
+ // "order_id": "198361cecdc65f9c8c9bb2fa68faec40"
863
+ // }
864
+ //
865
+ const result = this.parseOrder (response, market);
866
+ return this.extend (result, {
867
+ 'symbol': symbol,
868
+ 'side': side,
869
+ 'type': type,
870
+ 'amount': amount,
871
+ 'price': price,
872
+ });
873
+ }
874
+
875
+ async cancelOrder (id, symbol = undefined, params = {}) {
876
+ await this.loadMarkets ();
877
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
878
+ const orderType = this.safeString (params, 'type', defaultType);
879
+ params = this.omit (params, 'type');
880
+ const request = {
881
+ 'market': orderType,
882
+ 'order_id': id,
883
+ };
884
+ const response = await this.privatePostMarketOrderCancel (this.extend (request, params));
885
+ //
886
+ // {
887
+ // "code": 0,
888
+ // "success": [
889
+ // "198361cecdc65f9c8c9bb2fa68faec40",
890
+ // "3fb0d98e51c18954f10d439a9cf57de0"
891
+ // ],
892
+ // "error": [
893
+ // "78a7104e3c65cc0c5a212a53e76d0205"
894
+ // ]
895
+ // }
896
+ //
897
+ const canceledOrders = this.safeValue (response, 'success', []);
898
+ const numCanceledOrders = canceledOrders.length;
899
+ if (numCanceledOrders !== 1) {
900
+ throw new OrderNotFound (this.id + ' cancelOrder() ' + id + ' not found');
901
+ }
902
+ return response;
903
+ }
904
+
905
+ async cancelOrders (ids, symbol = undefined, params = {}) {
906
+ await this.loadMarkets ();
907
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
908
+ const orderType = this.safeString (params, 'type', defaultType);
909
+ params = this.omit (params, 'type');
910
+ const request = {
911
+ 'market': orderType,
912
+ 'order_id': ids.join (','),
913
+ };
914
+ const response = await this.privatePostCancelOrder (this.extend (request, params));
915
+ //
916
+ // {
917
+ // "code": 0,
918
+ // "success": [
919
+ // "198361cecdc65f9c8c9bb2fa68faec40",
920
+ // "3fb0d98e51c18954f10d439a9cf57de0"
921
+ // ],
922
+ // "error": [
923
+ // "78a7104e3c65cc0c5a212a53e76d0205"
924
+ // ]
925
+ // }
926
+ //
927
+ const canceledOrders = this.safeValue (response, 'success', []);
928
+ const numCanceledOrders = canceledOrders.length;
929
+ if (numCanceledOrders < 1) {
930
+ throw new OrderNotFound (this.id + ' cancelOrders() error');
931
+ }
932
+ return response;
933
+ }
934
+
935
+ parseOrderStatus (status) {
936
+ const statuses = {
937
+ '0': 'open',
938
+ '1': 'open', // partially filled
939
+ '2': 'closed',
940
+ '3': 'canceled',
941
+ '4': 'canceled', // partially filled and canceled
942
+ };
943
+ return this.safeString (statuses, status, status);
944
+ }
945
+
946
+ parseOrder (order, market = undefined) {
947
+ //
948
+ // createOrder
949
+ //
950
+ // {
951
+ // "code": 0,
952
+ // "order_id": "198361cecdc65f9c8c9bb2fa68faec40"
953
+ // }
954
+ //
955
+ // fetchOrder, fetchOpenOrders, fetchOrders
956
+ //
957
+ // {
958
+ // "symbol": "BTC_USDT",
959
+ // "order_id": "dd3164b333a4afa9d5730bb87f6db8b3",
960
+ // "created_date": 1562303547,
961
+ // "finished_date": 0,
962
+ // "price": 0.1,
963
+ // "amount": 1,
964
+ // "cash_amount": 1,
965
+ // "executed_amount": 0,
966
+ // "avg_price": 0,
967
+ // "status": 1,
968
+ // "type": "buy",
969
+ // "kind": "margin"
970
+ // }
971
+ //
972
+ const id = this.safeString (order, 'order_id');
973
+ const timestamp = this.safeTimestamp (order, 'created_date');
974
+ const lastTradeTimestamp = this.safeTimestamp (order, 'finished_date');
975
+ let side = this.safeString (order, 'type');
976
+ let type = undefined;
977
+ if (side !== undefined) {
978
+ const parts = side.split ('_');
979
+ const numParts = parts.length;
980
+ if (numParts > 1) {
981
+ side = parts[0];
982
+ type = parts[1];
983
+ } else {
984
+ type = 'limit';
985
+ }
986
+ }
987
+ const status = this.parseOrderStatus (this.safeString (order, 'status'));
988
+ const marketId = this.safeString (order, 'symbol');
989
+ const symbol = this.safeSymbol (marketId, market, '_');
990
+ const amountString = this.safeString (order, 'amount');
991
+ const filledString = this.safeString (order, 'executed_amount');
992
+ const priceString = this.safeString (order, 'price');
993
+ const averageString = this.safeString (order, 'avg_price');
994
+ return this.safeOrder ({
995
+ 'info': order,
996
+ 'id': id,
997
+ 'clientOrderId': undefined,
998
+ 'timestamp': timestamp,
999
+ 'datetime': this.iso8601 (timestamp),
1000
+ 'lastTradeTimestamp': lastTradeTimestamp,
1001
+ 'symbol': symbol,
1002
+ 'type': type,
1003
+ 'timeInForce': undefined,
1004
+ 'postOnly': undefined,
1005
+ 'side': side,
1006
+ 'price': priceString,
1007
+ 'stopPrice': undefined,
1008
+ 'amount': amountString,
1009
+ 'filled': filledString,
1010
+ 'remaining': undefined,
1011
+ 'cost': undefined,
1012
+ 'average': averageString,
1013
+ 'status': status,
1014
+ 'fee': undefined,
1015
+ 'trades': undefined,
1016
+ }, market);
1017
+ }
1018
+
1019
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1020
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
1021
+ const orderType = this.safeString (params, 'type', defaultType);
1022
+ params = this.omit (params, 'type');
1023
+ await this.loadMarkets ();
1024
+ let market = undefined;
1025
+ const request = {
1026
+ 'market': orderType,
1027
+ };
1028
+ if (symbol !== undefined) {
1029
+ market = this.market (symbol);
1030
+ request['symbol'] = market['id'];
1031
+ }
1032
+ const response = await this.privateGetMarketOrderCurrent (this.extend (request, params));
1033
+ //
1034
+ // {
1035
+ // "code": 0,
1036
+ // "data": [
1037
+ // {
1038
+ // "symbol": "BTC_USDT",
1039
+ // "order_id": "dd3164b333a4afa9d5730bb87f6db8b3",
1040
+ // "created_date": 1562303547,
1041
+ // "finished_date": 0,
1042
+ // "price": 0.1,
1043
+ // "amount": 1,
1044
+ // "cash_amount": 1,
1045
+ // "executed_amount": 0,
1046
+ // "avg_price": 0,
1047
+ // "status": 1,
1048
+ // "type": "buy",
1049
+ // "kind": "margin"
1050
+ // }
1051
+ // ]
1052
+ // }
1053
+ //
1054
+ const data = this.safeValue (response, 'data', []);
1055
+ return this.parseOrders (data, market, since, limit);
1056
+ }
1057
+
1058
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1059
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
1060
+ const orderType = this.safeString (params, 'type', defaultType);
1061
+ params = this.omit (params, 'type');
1062
+ await this.loadMarkets ();
1063
+ let market = undefined;
1064
+ const request = {
1065
+ 'market': orderType,
1066
+ };
1067
+ if (symbol !== undefined) {
1068
+ market = this.market (symbol);
1069
+ request['symbol'] = market['id'];
1070
+ }
1071
+ if (since !== undefined) {
1072
+ request['start_time'] = parseInt (since / 1000); // default 3 days from now, max 30 days
1073
+ }
1074
+ if (limit !== undefined) {
1075
+ request['limit'] = limit; // default 10, max 100
1076
+ }
1077
+ const response = await this.privateGetMarketOrderHistory (this.extend (request, params));
1078
+ //
1079
+ // {
1080
+ // "code": 0,
1081
+ // "data": [
1082
+ // {
1083
+ // "symbol": "BTC_USDT",
1084
+ // "order_id": "dd3164b333a4afa9d5730bb87f6db8b3",
1085
+ // "created_date": 1562303547,
1086
+ // "finished_date": 0,
1087
+ // "price": 0.1,
1088
+ // "amount": 1,
1089
+ // "cash_amount": 1,
1090
+ // "executed_amount": 0,
1091
+ // "avg_price": 0,
1092
+ // "status": 1,
1093
+ // "type": "buy",
1094
+ // "kind": "margin"
1095
+ // }
1096
+ // ]
1097
+ // }
1098
+ //
1099
+ const data = this.safeValue (response, 'data', []);
1100
+ return this.parseOrders (data, market, since, limit);
1101
+ }
1102
+
1103
+ async fetchOrder (id, symbol = undefined, params = {}) {
1104
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
1105
+ const orderType = this.safeString (params, 'type', defaultType);
1106
+ params = this.omit (params, 'type');
1107
+ await this.loadMarkets ();
1108
+ let market = undefined;
1109
+ if (symbol !== undefined) {
1110
+ market = this.market (symbol);
1111
+ }
1112
+ const request = {
1113
+ 'market': orderType,
1114
+ 'order_id': id,
1115
+ };
1116
+ const response = await this.privateGetMarketOrder (this.extend (request, params));
1117
+ //
1118
+ // {
1119
+ // "code": 0,
1120
+ // "data": [
1121
+ // {
1122
+ // "symbol": "BTC_USDT",
1123
+ // "order_id": "dd3164b333a4afa9d5730bb87f6db8b3",
1124
+ // "created_date": 1562303547,
1125
+ // "finished_date": 0,
1126
+ // "price": 0.1,
1127
+ // "amount": 1,
1128
+ // "cash_amount": 1,
1129
+ // "executed_amount": 0,
1130
+ // "avg_price": 0,
1131
+ // "status": 1,
1132
+ // "type": "buy",
1133
+ // "kind": "margin"
1134
+ // }
1135
+ // ]
1136
+ // }
1137
+ //
1138
+ const data = this.safeValue (response, 'data', []);
1139
+ const order = this.safeValue (data, 0);
1140
+ if (order === undefined) {
1141
+ throw new OrderNotFound (this.id + ' fetchOrder() order ' + id + ' not found');
1142
+ }
1143
+ return this.parseOrder (order, market);
1144
+ }
1145
+
1146
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1147
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
1148
+ const orderType = this.safeString (params, 'type', defaultType);
1149
+ params = this.omit (params, 'type');
1150
+ await this.loadMarkets ();
1151
+ let market = undefined;
1152
+ const request = {
1153
+ 'market': orderType,
1154
+ };
1155
+ if (symbol !== undefined) {
1156
+ market = this.market (symbol);
1157
+ request['symbol'] = market['id'];
1158
+ }
1159
+ if (since !== undefined) {
1160
+ request['start_time'] = parseInt (since / 1000); // default 3 days from now, max 30 days
1161
+ }
1162
+ if (limit !== undefined) {
1163
+ request['limit'] = limit; // default 10, max 100
1164
+ }
1165
+ const response = await this.privateGetMarketMytrades (this.extend (request, params));
1166
+ //
1167
+ // {
1168
+ // "list":[
1169
+ // {
1170
+ // "timestamp":1639506068,
1171
+ // "is_maker":false,
1172
+ // "id":"8975951332",
1173
+ // "amount":31.83,
1174
+ // "side":"sell_market",
1175
+ // "symbol":"DOGE_USDT",
1176
+ // "fee_currency":"USDT",
1177
+ // "fee":0.01163774826
1178
+ // ,"order_id":"32b169792f4a7a19e5907dc29fc123d4",
1179
+ // "price":0.182811
1180
+ // }
1181
+ // ],
1182
+ // "code": 0
1183
+ // }
1184
+ //
1185
+ const data = this.safeValue (response, 'list', []);
1186
+ return this.parseTrades (data, market, since, limit);
1187
+ }
1188
+
1189
+ parseLedgerEntryType (type) {
1190
+ const types = {};
1191
+ return this.safeString (types, type, type);
1192
+ }
1193
+
1194
+ parseLedgerEntry (item, currency = undefined) {
1195
+ //
1196
+ // {
1197
+ // "currency_mark": "BTC",
1198
+ // "type": 100234,
1199
+ // "num": 28457,
1200
+ // "balance": 0.1,
1201
+ // "time": 1546272000
1202
+ // }
1203
+ //
1204
+ const id = this.safeString (item, 'num');
1205
+ const account = undefined;
1206
+ const type = this.parseLedgerEntryType (this.safeString (item, 'type'));
1207
+ const code = this.safeCurrencyCode (this.safeString (item, 'currency_mark'), currency);
1208
+ const timestamp = this.safeTimestamp (item, 'time');
1209
+ const before = undefined;
1210
+ const after = this.safeNumber (item, 'balance');
1211
+ const status = 'ok';
1212
+ return {
1213
+ 'info': item,
1214
+ 'id': id,
1215
+ 'direction': undefined,
1216
+ 'account': account,
1217
+ 'referenceId': undefined,
1218
+ 'referenceAccount': undefined,
1219
+ 'type': type,
1220
+ 'currency': code,
1221
+ 'amount': undefined,
1222
+ 'before': before,
1223
+ 'after': after,
1224
+ 'status': status,
1225
+ 'timestamp': timestamp,
1226
+ 'datetime': this.iso8601 (timestamp),
1227
+ 'fee': undefined,
1228
+ };
1229
+ }
1230
+
1231
+ async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
1232
+ const defaultType = this.safeString (this.options, 'defaultType', 'spot');
1233
+ const orderType = this.safeString (params, 'type', defaultType);
1234
+ params = this.omit (params, 'type');
1235
+ await this.loadMarkets ();
1236
+ const request = {
1237
+ 'market': orderType,
1238
+ };
1239
+ let currency = undefined;
1240
+ if (code !== undefined) {
1241
+ currency = this.currency (code);
1242
+ request['currency_mark'] = currency['id'];
1243
+ }
1244
+ if (since !== undefined) {
1245
+ request['start_time'] = parseInt (since / 1000);
1246
+ }
1247
+ if (limit !== undefined) {
1248
+ request['limit'] = limit; // default 100, max 1000
1249
+ }
1250
+ const response = await this.privateGetMarketFinancelog (this.extend (request, params));
1251
+ //
1252
+ // {
1253
+ // "code": 0,
1254
+ // "data": {
1255
+ // "total": 521,
1256
+ // "finance": [
1257
+ // {
1258
+ // "currency_mark": "BTC",
1259
+ // "type": 100234,
1260
+ // "num": 28457,
1261
+ // "balance": 0.1,
1262
+ // "time": 1546272000
1263
+ // }
1264
+ // ]
1265
+ // }
1266
+ // }
1267
+ //
1268
+ const data = this.safeValue (response, 'data', {});
1269
+ const items = this.safeValue (data, 'finance', []);
1270
+ return this.parseLedger (items, currency, since, limit);
1271
+ }
1272
+
1273
+ parseDepositAddress (depositAddress, currency = undefined) {
1274
+ //
1275
+ // {
1276
+ // "addressTag":"",
1277
+ // "address":"0xf1104d9f8624f89775a3e9d480fc0e75a8ef4373",
1278
+ // "currency":"USDT",
1279
+ // "chain":"ERC20"
1280
+ // }
1281
+ //
1282
+ const address = this.safeString (depositAddress, 'address');
1283
+ const tag = this.safeString (depositAddress, 'addressTag');
1284
+ const currencyId = this.safeStringUpper (depositAddress, 'currency');
1285
+ const code = this.safeCurrencyCode (currencyId);
1286
+ return {
1287
+ 'info': depositAddress,
1288
+ 'currency': code,
1289
+ 'address': address,
1290
+ 'tag': tag,
1291
+ 'network': undefined,
1292
+ };
1293
+ }
1294
+
1295
+ async fetchDepositAddress (code, params = {}) {
1296
+ await this.loadMarkets ();
1297
+ const currency = this.currency (code);
1298
+ const request = {
1299
+ 'currency': currency['id'],
1300
+ };
1301
+ const response = await this.privateGetDepositAddress (this.extend (request, params));
1302
+ //
1303
+ // {
1304
+ // "data":[
1305
+ // {
1306
+ // "addressTag":"",
1307
+ // "address":"0xf1104d9f8624f89775a3e9d480fc0e75a8ef4373",
1308
+ // "currency":"USDT",
1309
+ // "chain":"ERC20"
1310
+ // }
1311
+ // ],
1312
+ // "code":200
1313
+ // }
1314
+ //
1315
+ const data = this.safeValue (response, 'data', []);
1316
+ const addresses = this.parseDepositAddresses (data);
1317
+ const address = this.safeValue (addresses, code);
1318
+ if (address === undefined) {
1319
+ throw new InvalidAddress (this.id + ' fetchDepositAddress() did not return an address for ' + code + ' - create the deposit address in the user settings on the exchange website first.');
1320
+ }
1321
+ return address;
1322
+ }
1323
+
1324
+ async fetchTransactionsByType (type, code = undefined, since = undefined, limit = undefined, params = {}) {
1325
+ await this.loadMarkets ();
1326
+ let currency = undefined;
1327
+ const request = {
1328
+ // 'currency': currency['id'],
1329
+ // 'from': 'fromId', // When direct is' prev ', from is 1, returning from old to new ascending, when direct is' next ', from is the ID of the most recent record, returned from the old descending order
1330
+ // 'size': 100, // default 100, max 500
1331
+ // 'direct': 'prev', // "prev" ascending, "next" descending
1332
+ };
1333
+ if (code !== undefined) {
1334
+ currency = this.currency (code);
1335
+ request['currency'] = currency['id'];
1336
+ }
1337
+ if (limit !== undefined) {
1338
+ request['size'] = Math.min (500, limit);
1339
+ }
1340
+ const method = (type === 'deposit') ? 'privateGetDepositHistory' : 'privateGetWithdrawHistory';
1341
+ const response = await this[method] (this.extend (request, params));
1342
+ //
1343
+ // {
1344
+ // "code": 200,
1345
+ // "data": [
1346
+ // {
1347
+ // "id": 1171,
1348
+ // "currency": "xrp",
1349
+ // "hash": "ed03094b84eafbe4bc16e7ef766ee959885ee5bcb265872baaa9c64e1cf86c2b",
1350
+ // "chain": "",
1351
+ // "amount": 7.457467,
1352
+ // "address": "rae93V8d2mdoUQHwBDBdM4NHCMehRJAsbm",
1353
+ // "memo": "100040",
1354
+ // "fee": 0,
1355
+ // "state": "safe",
1356
+ // "created_date": "2020-04-20 11:23:00",
1357
+ // "finished_date": "2020-04-20 13:23:00"
1358
+ // },
1359
+ // ]
1360
+ // }
1361
+ //
1362
+ const data = this.safeValue (response, 'data', []);
1363
+ return this.parseTransactions (data, currency, since, limit, { 'type': type });
1364
+ }
1365
+
1366
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1367
+ return await this.fetchTransactionsByType ('deposit', code, since, limit, params);
1368
+ }
1369
+
1370
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1371
+ return await this.fetchTransactionsByType ('withdrawal', code, since, limit, params);
1372
+ }
1373
+
1374
+ parseTransactionStatus (status) {
1375
+ // deposit state includes: 1 (in deposit), 2 (to be confirmed), 3 (successfully deposited), 4 (stopped)
1376
+ // withdrawal state includes: 1 (application in progress), 2 (to be confirmed), 3 (completed), 4 (rejected)
1377
+ const statuses = {
1378
+ '1': 'pending', // in Progress
1379
+ '2': 'pending', // to be confirmed
1380
+ '3': 'ok', // Completed
1381
+ '4': 'failed', // Rejected
1382
+ };
1383
+ return this.safeString (statuses, status, status);
1384
+ }
1385
+
1386
+ parseTransaction (transaction, currency = undefined) {
1387
+ //
1388
+ // withdraw
1389
+ //
1390
+ // {
1391
+ // "code": 200,
1392
+ // "withdraw_id": 700
1393
+ // }
1394
+ //
1395
+ // fetchDeposits, fetchWithdrawals
1396
+ //
1397
+ // {
1398
+ // "id": 1171,
1399
+ // "currency": "xrp",
1400
+ // "hash": "ed03094b84eafbe4bc16e7ef766ee959885ee5bcb265872baaa9c64e1cf86c2b",
1401
+ // "chain": "",
1402
+ // "amount": 7.457467,
1403
+ // "address": "rae93V8d2mdoUQHwBDBdM4NHCMehRJAsbm",
1404
+ // "memo": "100040",
1405
+ // "fee": 0,
1406
+ // "state": "safe",
1407
+ // "created_date": "2020-04-20 11:23:00",
1408
+ // "finished_date": "2020-04-20 13:23:00"
1409
+ // }
1410
+ //
1411
+ const id = this.safeString2 (transaction, 'id', 'withdraw_id');
1412
+ const address = this.safeString (transaction, 'address');
1413
+ let tag = this.safeString (transaction, 'memo'); // set but unused
1414
+ if (tag !== undefined) {
1415
+ if (tag.length < 1) {
1416
+ tag = undefined;
1417
+ }
1418
+ }
1419
+ const txid = this.safeString (transaction, 'hash');
1420
+ const currencyId = this.safeStringUpper (transaction, 'currency');
1421
+ const code = this.safeCurrencyCode (currencyId, currency);
1422
+ const timestamp = this.parse8601 (this.safeString (transaction, 'created_date'));
1423
+ const updated = this.parse8601 (this.safeString (transaction, 'finished_date'));
1424
+ const status = this.parseTransactionStatus (this.safeString (transaction, 'state'));
1425
+ const amount = this.safeNumber (transaction, 'amount');
1426
+ const feeCost = this.safeNumber (transaction, 'fee');
1427
+ let fee = undefined;
1428
+ if (feeCost !== undefined) {
1429
+ fee = { 'currency': code, 'cost': feeCost };
1430
+ }
1431
+ let network = this.safeString (transaction, 'chain');
1432
+ if (network === '') {
1433
+ network = undefined;
1434
+ }
1435
+ return {
1436
+ 'info': transaction,
1437
+ 'id': id,
1438
+ 'txid': txid,
1439
+ 'timestamp': timestamp,
1440
+ 'datetime': this.iso8601 (timestamp),
1441
+ 'network': network,
1442
+ 'address': address,
1443
+ 'addressTo': address,
1444
+ 'addressFrom': undefined,
1445
+ 'tag': tag,
1446
+ 'tagTo': tag,
1447
+ 'tagFrom': undefined,
1448
+ 'type': undefined,
1449
+ 'amount': amount,
1450
+ 'currency': code,
1451
+ 'status': status,
1452
+ 'updated': updated,
1453
+ 'fee': fee,
1454
+ };
1455
+ }
1456
+
1457
+ parseTransferStatus (status) {
1458
+ const statuses = {
1459
+ '0': 'ok',
1460
+ };
1461
+ return this.safeString (statuses, status, status);
1462
+ }
1463
+
1464
+ parseTransfer (transfer, currency = undefined) {
1465
+ //
1466
+ // {
1467
+ // "code": 0
1468
+ // }
1469
+ //
1470
+ return {
1471
+ 'info': transfer,
1472
+ 'id': undefined,
1473
+ 'timestamp': undefined,
1474
+ 'datetime': undefined,
1475
+ 'currency': this.safeCurrencyCode (undefined, currency),
1476
+ 'amount': this.safeNumber (transfer, 'amount'),
1477
+ 'fromAccount': this.safeString (transfer, 'fromAccount'),
1478
+ 'toAccount': this.safeString (transfer, 'toAccount'),
1479
+ 'status': this.parseTransferStatus (this.safeString (transfer, 'code')),
1480
+ };
1481
+ }
1482
+
1483
+ async transfer (code, amount, fromAccount, toAccount, params = {}) {
1484
+ await this.loadMarkets ();
1485
+ const currency = this.currency (code);
1486
+ const accountsByType = this.safeValue (this.options, 'accountsByType', {});
1487
+ const fromId = this.safeString (accountsByType, fromAccount, fromAccount);
1488
+ const toId = this.safeString (accountsByType, toAccount, toAccount);
1489
+ const request = {
1490
+ 'currency_mark': currency['id'],
1491
+ 'num': parseFloat (this.currencyToPrecision (code, amount)),
1492
+ 'from': fromId, // 1 = SPOT, 2 = MARGIN, 3 = OTC
1493
+ 'to': toId, // 1 = SPOT, 2 = MARGIN, 3 = OTC
1494
+ };
1495
+ const response = await this.privatePostTransfer (this.extend (request, params));
1496
+ //
1497
+ // {
1498
+ // "code": 0
1499
+ // }
1500
+ //
1501
+ const transfer = this.parseTransfer (response, currency);
1502
+ return this.extend (transfer, {
1503
+ 'amount': amount,
1504
+ 'currency': code,
1505
+ 'fromAccount': fromAccount,
1506
+ 'toAccount': toAccount,
1507
+ });
1508
+ }
1509
+
1510
+ async withdraw (code, amount, address, tag = undefined, params = {}) {
1511
+ [ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
1512
+ this.checkAddress (address);
1513
+ await this.loadMarkets ();
1514
+ const currency = this.currency (code);
1515
+ const request = {
1516
+ // 'chain': 'ERC20', 'OMNI', 'TRC20', // required for USDT
1517
+ 'address': address,
1518
+ 'amount': parseFloat (amount),
1519
+ 'currency': currency['id'],
1520
+ };
1521
+ if (tag !== undefined) {
1522
+ request['memo'] = tag;
1523
+ }
1524
+ const response = await this.privatePostWithdrawNew (this.extend (request, params));
1525
+ //
1526
+ // {
1527
+ // "code": 200,
1528
+ // "withdraw_id": 700
1529
+ // }
1530
+ //
1531
+ return this.parseTransaction (response, currency);
1532
+ }
1533
+
1534
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1535
+ const version = this.version;
1536
+ let url = this.urls['api'] + '/' + version + '/' + this.implodeParams (path, params);
1537
+ const query = this.omit (params, this.extractParams (path));
1538
+ const urlencoded = this.urlencode (this.keysort (query));
1539
+ if (api === 'private') {
1540
+ const nonce = this.nonce ().toString ();
1541
+ const auth = urlencoded;
1542
+ // the signature is not time-limited :\
1543
+ const signature = this.hmac (this.encode (auth), this.encode (this.secret));
1544
+ if (method === 'GET') {
1545
+ if (urlencoded) {
1546
+ url += '?' + urlencoded;
1547
+ }
1548
+ } else if (method === 'POST') {
1549
+ headers = {
1550
+ 'Content-Type': 'application/x-www-form-urlencoded',
1551
+ };
1552
+ if (urlencoded) {
1553
+ body = urlencoded;
1554
+ }
1555
+ }
1556
+ headers = {
1557
+ 'ACCESS-KEY': this.apiKey,
1558
+ 'ACCESS-SIGN': signature,
1559
+ 'ACCESS-TIMESTAMP': nonce,
1560
+ };
1561
+ } else {
1562
+ if (urlencoded) {
1563
+ url += '?' + urlencoded;
1564
+ }
1565
+ }
1566
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1567
+ }
1568
+
1569
+ handleErrors (statusCode, statusText, url, method, responseHeaders, responseBody, response, requestHeaders, requestBody) {
1570
+ if (!response) {
1571
+ return; // fall back to default error handler
1572
+ }
1573
+ const code = this.safeString (response, 'code');
1574
+ if ((code === '0') || (code === '200')) {
1575
+ return; // no error
1576
+ }
1577
+ const feedback = this.id + ' ' + responseBody;
1578
+ if (code === undefined) {
1579
+ throw new BadResponse (feedback);
1580
+ }
1581
+ const unknownError = [ ExchangeError, feedback ];
1582
+ const [ ExceptionClass, message ] = this.safeValue (this.exceptions['exact'], code, unknownError);
1583
+ throw new ExceptionClass (message);
1584
+ }
1585
+ };