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/bw.js ADDED
@@ -0,0 +1,1265 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { RateLimitExceeded, BadSymbol, OrderNotFound, ExchangeError, AuthenticationError, ArgumentsRequired, ExchangeNotAvailable } = require ('./base/errors');
7
+
8
+ // ---------------------------------------------------------------------------
9
+
10
+ module.exports = class bw extends Exchange {
11
+ describe () {
12
+ return this.deepExtend (super.describe (), {
13
+ 'id': 'bw',
14
+ 'name': 'BW',
15
+ 'countries': [ 'CN' ],
16
+ 'rateLimit': 1500,
17
+ 'version': 'v1',
18
+ 'has': {
19
+ 'CORS': undefined,
20
+ 'spot': true,
21
+ 'margin': undefined, // has but unimplemented
22
+ 'swap': undefined, // has but unimplemented
23
+ 'future': undefined,
24
+ 'option': undefined,
25
+ 'cancelAllOrders': undefined,
26
+ 'cancelOrder': true,
27
+ 'cancelOrders': undefined,
28
+ 'createDepositAddress': undefined,
29
+ 'createLimitOrder': true,
30
+ 'createMarketOrder': undefined,
31
+ 'createOrder': true,
32
+ 'editOrder': undefined,
33
+ 'fetchBalance': true,
34
+ 'fetchBidsAsks': undefined,
35
+ 'fetchClosedOrders': true,
36
+ 'fetchCurrencies': true,
37
+ 'fetchDepositAddress': true,
38
+ 'fetchDeposits': true,
39
+ 'fetchFundingFees': undefined,
40
+ 'fetchL2OrderBook': undefined,
41
+ 'fetchLedger': undefined,
42
+ 'fetchMarkets': true,
43
+ 'fetchMyTrades': undefined,
44
+ 'fetchOHLCV': true,
45
+ 'fetchOpenOrders': true,
46
+ 'fetchOrder': true,
47
+ 'fetchOrderBook': true,
48
+ 'fetchOrderBooks': undefined,
49
+ 'fetchOrders': true,
50
+ 'fetchTicker': true,
51
+ 'fetchTickers': true,
52
+ 'fetchTrades': true,
53
+ 'fetchTradingFee': false,
54
+ 'fetchTradingFees': true,
55
+ 'fetchTradingLimits': undefined,
56
+ 'fetchTransactions': undefined,
57
+ 'fetchWithdrawals': true,
58
+ 'withdraw': undefined,
59
+ },
60
+ 'timeframes': {
61
+ '1m': '1M',
62
+ '5m': '5M',
63
+ '15m': '15M',
64
+ '30m': '30M',
65
+ '1h': '1H',
66
+ '1w': '1W',
67
+ },
68
+ 'hostname': 'bw.com', // set to 'bw.io' for China mainland
69
+ 'urls': {
70
+ 'logo': 'https://user-images.githubusercontent.com/1294454/69436317-31128c80-0d52-11ea-91d1-eb7bb5818812.jpg',
71
+ 'api': 'https://www.{hostname}',
72
+ 'www': 'https://www.bw.com',
73
+ 'doc': 'https://github.com/bw-exchange/api_docs_en/wiki',
74
+ 'fees': 'https://www.bw.com/feesRate',
75
+ 'referral': 'https://www.bw.com/regGetCommission/N3JuT1R3bWxKTE0',
76
+ },
77
+ 'requiredCredentials': {
78
+ 'apiKey': true,
79
+ 'secret': true,
80
+ },
81
+ 'fees': {
82
+ 'trading': {
83
+ 'tierBased': true,
84
+ 'percentage': true,
85
+ 'taker': this.parseNumber ('0.002'),
86
+ 'maker': this.parseNumber ('0.002'),
87
+ },
88
+ 'funding': {
89
+ },
90
+ },
91
+ 'exceptions': {
92
+ 'exact': {
93
+ '999': AuthenticationError,
94
+ '1000': ExchangeNotAvailable, // {"datas":null,"resMsg":{"message":"getKlines error:data not exitsts\uff0cplease wait ,dataType=4002_KLINE_1M","method":null,"code":"1000"}}
95
+ '2012': OrderNotFound, // {"datas":null,"resMsg":{"message":"entrust not exists or on dealing with system","method":null,"code":"2012"}}
96
+ '5017': BadSymbol, // {"datas":null,"resMsg":{"message":"market not exist","method":null,"code":"5017"}}
97
+ '10001': RateLimitExceeded, // {"resMsg":{"code":"10001","message":"API frequency limit"}}
98
+ },
99
+ },
100
+ 'api': {
101
+ 'public': {
102
+ 'get': [
103
+ 'api/data/v1/klines',
104
+ 'api/data/v1/ticker',
105
+ 'api/data/v1/tickers',
106
+ 'api/data/v1/trades',
107
+ 'api/data/v1/entrusts',
108
+ 'exchange/config/controller/website/marketcontroller/getByWebId',
109
+ 'exchange/config/controller/website/currencycontroller/getCurrencyList',
110
+ ],
111
+ },
112
+ 'private': {
113
+ 'get': [
114
+ 'exchange/entrust/controller/website/EntrustController/getEntrustById',
115
+ 'exchange/entrust/controller/website/EntrustController/getUserEntrustRecordFromCacheWithPage',
116
+ 'exchange/entrust/controller/website/EntrustController/getUserEntrustList',
117
+ 'exchange/fund/controller/website/fundwebsitecontroller/getwithdrawaddress',
118
+ 'exchange/fund/controller/website/fundwebsitecontroller/getpayoutcoinrecord',
119
+ 'exchange/entrust/controller/website/EntrustController/getUserEntrustList',
120
+ // the docs say that the following URLs are HTTP POST
121
+ // in the docs header and HTTP GET in the docs body
122
+ // the docs contradict themselves, a typo most likely
123
+ // the actual HTTP method is POST for this endpoint
124
+ // 'exchange/fund/controller/website/fundcontroller/getPayinAddress',
125
+ // 'exchange/fund/controller/website/fundcontroller/getPayinCoinRecord',
126
+ ],
127
+ 'post': [
128
+ 'exchange/fund/controller/website/fundcontroller/getPayinAddress', // see the comment above
129
+ 'exchange/fund/controller/website/fundcontroller/getPayinCoinRecord', // see the comment above
130
+ 'exchange/fund/controller/website/fundcontroller/findbypage',
131
+ 'exchange/entrust/controller/website/EntrustController/addEntrust',
132
+ 'exchange/entrust/controller/website/EntrustController/cancelEntrust',
133
+ ],
134
+ },
135
+ },
136
+ });
137
+ }
138
+
139
+ async fetchMarkets (params = {}) {
140
+ const response = await this.publicGetExchangeConfigControllerWebsiteMarketcontrollerGetByWebId (params);
141
+ //
142
+ // {
143
+ // resMsg: {
144
+ // method: null,
145
+ // code: '1',
146
+ // message: 'success !'
147
+ // },
148
+ // datas: [
149
+ // {
150
+ // leverMultiple: '10',
151
+ // amountDecimal: '4',
152
+ // minAmount: '0.0100000000',
153
+ // modifyUid: null,
154
+ // buyerCurrencyId: '11',
155
+ // isCombine: '0',
156
+ // priceDecimal: '3',
157
+ // combineMarketId: '',
158
+ // openPrice: '0',
159
+ // leverEnable: true,
160
+ // marketId: '291',
161
+ // serverId: 'entrust_bw_2',
162
+ // isMining: '0',
163
+ // webId: '102',
164
+ // modifyTime: '1581595375498',
165
+ // defaultFee: '0.00200000',
166
+ // sellerCurrencyId: '7',
167
+ // createTime: '0',
168
+ // state: '1',
169
+ // name: 'eos_usdt',
170
+ // leverType: '2',
171
+ // createUid: null,
172
+ // orderNum: null,
173
+ // openTime: '1574956800000'
174
+ // },
175
+ // ]
176
+ // }
177
+ //
178
+ const markets = this.safeValue (response, 'datas', []);
179
+ const result = [];
180
+ for (let i = 0; i < markets.length; i++) {
181
+ const market = markets[i];
182
+ const id = this.safeString (market, 'marketId');
183
+ const numericId = parseInt (id);
184
+ const name = this.safeStringUpper (market, 'name');
185
+ let [ base, quote ] = name.split ('_');
186
+ base = this.safeCurrencyCode (base);
187
+ quote = this.safeCurrencyCode (quote);
188
+ const baseId = this.safeString (market, 'sellerCurrencyId');
189
+ const quoteId = this.safeString (market, 'buyerCurrencyId');
190
+ const state = this.safeInteger (market, 'state');
191
+ const fee = this.safeNumber (market, 'defaultFee');
192
+ result.push ({
193
+ 'id': id,
194
+ 'numericId': numericId,
195
+ 'symbol': base + '/' + quote,
196
+ 'base': base,
197
+ 'quote': quote,
198
+ 'settle': undefined,
199
+ 'baseId': baseId,
200
+ 'quoteId': quoteId,
201
+ 'settleId': undefined,
202
+ 'baseNumericId': parseInt (baseId),
203
+ 'quoteNumericId': parseInt (quoteId),
204
+ 'type': 'spot',
205
+ 'spot': true,
206
+ 'margin': false,
207
+ 'swap': false,
208
+ 'future': false,
209
+ 'option': false,
210
+ 'active': (state === 1),
211
+ 'contract': false,
212
+ 'linear': undefined,
213
+ 'inverse': undefined,
214
+ 'taker': fee,
215
+ 'maker': fee,
216
+ 'contractSize': undefined,
217
+ 'expiry': undefined,
218
+ 'expiryDatetime': undefined,
219
+ 'strike': undefined,
220
+ 'optionType': undefined,
221
+ 'precision': {
222
+ 'amount': this.safeInteger (market, 'amountDecimal'),
223
+ 'price': this.safeInteger (market, 'priceDecimal'),
224
+ },
225
+ 'limits': {
226
+ 'leverage': {
227
+ 'min': undefined,
228
+ 'max': undefined,
229
+ },
230
+ 'amount': {
231
+ 'min': this.safeNumber (market, 'minAmount'),
232
+ 'max': undefined,
233
+ },
234
+ 'price': {
235
+ 'min': this.parseNumber ('0'),
236
+ 'max': undefined,
237
+ },
238
+ 'cost': {
239
+ 'min': this.parseNumber ('0'),
240
+ 'max': undefined,
241
+ },
242
+ },
243
+ 'info': market,
244
+ });
245
+ }
246
+ return result;
247
+ }
248
+
249
+ async fetchCurrencies (params = {}) {
250
+ const response = await this.publicGetExchangeConfigControllerWebsiteCurrencycontrollerGetCurrencyList (params);
251
+ //
252
+ // {
253
+ // "datas":[
254
+ // {
255
+ // "currencyId":"456",
256
+ // "name":"pan",
257
+ // "alias":"pan",
258
+ // "logo":"pan.svg",
259
+ // "description":"pan",
260
+ // "descriptionEnglish":"pan",
261
+ // "defaultDecimal":2,
262
+ // "createUid":null,
263
+ // "createTime":1574068133762,
264
+ // "modifyUid":null,
265
+ // "modifyTime":0,
266
+ // "state":1,
267
+ // "mark":"pan",
268
+ // "totalNumber":"0",
269
+ // "publishNumber":"0",
270
+ // "marketValue":"0",
271
+ // "isLegalCoin":0,
272
+ // "needBlockUrl":1,
273
+ // "blockChainUrl":"https://etherscan.io/tx/",
274
+ // "tradeSearchUrl":null,
275
+ // "tokenCoinsId":0,
276
+ // "isMining":"0",
277
+ // "arithmetic":null,
278
+ // "founder":"bw_nxwal",
279
+ // "teamAddress":null,
280
+ // "remark":null,
281
+ // "tokenName":"ethw2",
282
+ // "isMemo":0,
283
+ // "websiteCurrencyId":"7rhqoHLohkG",
284
+ // "drawFlag":0,
285
+ // "rechargeFlag":1,
286
+ // "drawFee":"0.03000000",
287
+ // "onceDrawLimit":100,
288
+ // "dailyDrawLimit":500,
289
+ // "timesFreetrial":"0",
290
+ // "hourFreetrial":"0",
291
+ // "dayFreetrial":"0",
292
+ // "minFee":"0",
293
+ // "inConfigTimes":7,
294
+ // "outConfigTimes":7,
295
+ // "minCash":"0.06000000",
296
+ // "limitAmount":"0",
297
+ // "zbExist":false,
298
+ // "zone":1
299
+ // },
300
+ // ],
301
+ // "resMsg": { "message":"success !", "method":null, "code":"1" }
302
+ // }
303
+ //
304
+ const currencies = this.safeValue (response, 'datas', []);
305
+ const result = {};
306
+ for (let i = 0; i < currencies.length; i++) {
307
+ const currency = currencies[i];
308
+ const id = this.safeString (currency, 'currencyId');
309
+ const code = this.safeCurrencyCode (this.safeStringUpper (currency, 'name'));
310
+ const state = this.safeInteger (currency, 'state');
311
+ const rechargeFlag = this.safeInteger (currency, 'rechargeFlag');
312
+ const drawFlag = this.safeInteger (currency, 'drawFlag');
313
+ const deposit = rechargeFlag === 1;
314
+ const withdraw = drawFlag === 1;
315
+ const active = state === 1;
316
+ result[code] = {
317
+ 'id': id,
318
+ 'code': code,
319
+ 'info': currency,
320
+ 'name': code,
321
+ 'active': active,
322
+ 'deposit': deposit,
323
+ 'withdraw': withdraw,
324
+ 'fee': this.safeNumber (currency, 'drawFee'),
325
+ 'precision': undefined,
326
+ 'limits': {
327
+ 'amount': {
328
+ 'min': this.safeNumber (currency, 'limitAmount', 0),
329
+ 'max': undefined,
330
+ },
331
+ 'withdraw': {
332
+ 'min': undefined,
333
+ 'max': this.safeNumber (currency, 'onceDrawLimit'),
334
+ },
335
+ },
336
+ };
337
+ }
338
+ return result;
339
+ }
340
+
341
+ parseTicker (ticker, market = undefined) {
342
+ //
343
+ // [
344
+ // "281", // market id
345
+ // "9754.4", // last
346
+ // "9968.8", // high
347
+ // "9631.5", // low
348
+ // "47865.6432", // base volume
349
+ // "-2.28", // change
350
+ // // closing price for last 6 hours
351
+ // "[[1, 9750.1], [2, 9737.1], [3, 9727.5], [4, 9722], [5, 9722.1], [6, 9754.4]]",
352
+ // "9752.12", // bid
353
+ // "9756.69", // ask
354
+ // "469849357.2364" // quote volume
355
+ // ]
356
+ //
357
+ const marketId = this.safeString (ticker, 0);
358
+ market = this.safeMarket (marketId, market);
359
+ const symbol = market['symbol'];
360
+ const timestamp = this.milliseconds ();
361
+ const close = this.safeString (ticker, 1);
362
+ const bid = this.safeValue (ticker, 'bid', {});
363
+ const ask = this.safeValue (ticker, 'ask', {});
364
+ return this.safeTicker ({
365
+ 'symbol': symbol,
366
+ 'timestamp': timestamp,
367
+ 'datetime': this.iso8601 (timestamp),
368
+ 'high': this.safeString (ticker, 2),
369
+ 'low': this.safeString (ticker, 3),
370
+ 'bid': this.safeString (ticker, 7),
371
+ 'bidVolume': this.safeString (bid, 'quantity'),
372
+ 'ask': this.safeString (ticker, 8),
373
+ 'askVolume': this.safeString (ask, 'quantity'),
374
+ 'vwap': undefined,
375
+ 'open': undefined,
376
+ 'close': close,
377
+ 'last': close,
378
+ 'previousClose': undefined,
379
+ 'change': this.safeString (ticker, 5),
380
+ 'percentage': undefined,
381
+ 'average': undefined,
382
+ 'baseVolume': this.safeString (ticker, 4),
383
+ 'quoteVolume': this.safeString (ticker, 9),
384
+ 'info': ticker,
385
+ }, market, false);
386
+ }
387
+
388
+ async fetchTicker (symbol, params = {}) {
389
+ await this.loadMarkets ();
390
+ const market = this.market (symbol);
391
+ const request = {
392
+ 'marketId': market['id'],
393
+ };
394
+ const response = await this.publicGetApiDataV1Ticker (this.extend (request, params));
395
+ //
396
+ // {
397
+ // "datas": [
398
+ // "281",
399
+ // "7601.99",
400
+ // "8126.5",
401
+ // "7474.68",
402
+ // "47004.8708",
403
+ // "-6.18",
404
+ // "[[1, 7800.34], [2, 7626.41], [3, 7609.97], [4, 7569.04], [5, 7577.93], [6, 7601.99]]",
405
+ // "7600.24",
406
+ // "7603.69",
407
+ // "371968300.0119",
408
+ // ],
409
+ // "resMsg": { "message": "success !", "method": null, "code": "1" }
410
+ // }
411
+ //
412
+ const ticker = this.safeValue (response, 'datas', []);
413
+ return this.parseTicker (ticker, market);
414
+ }
415
+
416
+ async fetchTickers (symbols = undefined, params = {}) {
417
+ await this.loadMarkets ();
418
+ const response = await this.publicGetApiDataV1Tickers (params);
419
+ //
420
+ // {
421
+ // "datas": [
422
+ // [
423
+ // "4051",
424
+ // "0.00194",
425
+ // "0.00863",
426
+ // "0.0012",
427
+ // "1519020",
428
+ // "-38.22",
429
+ // "[[1, 0.0023], [2, 0.00198], [3, 0.00199], [4, 0.00195], [5, 0.00199], [6, 0.00194]]",
430
+ // "0.00123",
431
+ // "0.0045",
432
+ // "4466.8104",
433
+ // ],
434
+ // ],
435
+ // "resMsg": { "message": "success !", "method": null, "code": "1" },
436
+ // }
437
+ //
438
+ const datas = this.safeValue (response, 'datas', []);
439
+ const result = {};
440
+ for (let i = 0; i < datas.length; i++) {
441
+ const ticker = this.parseTicker (datas[i]);
442
+ const symbol = ticker['symbol'];
443
+ if ((symbols === undefined) || this.inArray (symbol, symbols)) {
444
+ result[symbol] = ticker;
445
+ }
446
+ }
447
+ return this.filterByArray (result, 'symbol', symbols);
448
+ }
449
+
450
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
451
+ await this.loadMarkets ();
452
+ const market = this.market (symbol);
453
+ const request = {
454
+ 'marketId': market['id'],
455
+ };
456
+ if (limit !== undefined) {
457
+ request['dataSize'] = limit;
458
+ }
459
+ const response = await this.publicGetApiDataV1Entrusts (this.extend (request, params));
460
+ //
461
+ // {
462
+ // "datas": {
463
+ // "asks": [
464
+ // [ "9740.43", "0.0083" ],
465
+ // ],
466
+ // "bids": [
467
+ // [ "9734.33", "0.0133" ],
468
+ // ],
469
+ // "timestamp": "1569303520",
470
+ // },
471
+ // "resMsg": {
472
+ // "message": "success !",
473
+ // "method": null,
474
+ // "code": "1",
475
+ // },
476
+ // }
477
+ //
478
+ const orderbook = this.safeValue (response, 'datas', []);
479
+ const timestamp = this.safeTimestamp (orderbook, 'timestamp');
480
+ return this.parseOrderBook (orderbook, symbol, timestamp);
481
+ }
482
+
483
+ parseTrade (trade, market = undefined) {
484
+ //
485
+ // fetchTrades (public)
486
+ //
487
+ // [
488
+ // "T", // trade
489
+ // "281", // market id
490
+ // "1569303302", // timestamp
491
+ // "BTC_USDT", // market name
492
+ // "ask", // side
493
+ // "9745.08", // price
494
+ // "0.0026" // amount
495
+ // ]
496
+ //
497
+ // fetchMyTrades (private)
498
+ //
499
+ // ...
500
+ //
501
+ const timestamp = this.safeTimestamp (trade, 2);
502
+ const priceString = this.safeString (trade, 5);
503
+ const amountString = this.safeString (trade, 6);
504
+ let marketId = this.safeString (trade, 1);
505
+ let delimiter = undefined;
506
+ if (marketId !== undefined) {
507
+ if (!(marketId in this.markets_by_id)) {
508
+ delimiter = '_';
509
+ marketId = this.safeString (trade, 3);
510
+ }
511
+ }
512
+ market = this.safeMarket (marketId, market, delimiter);
513
+ const sideString = this.safeString (trade, 4);
514
+ const side = (sideString === 'ask') ? 'sell' : 'buy';
515
+ return this.safeTrade ({
516
+ 'id': undefined,
517
+ 'timestamp': timestamp,
518
+ 'datetime': this.iso8601 (timestamp),
519
+ 'symbol': market['symbol'],
520
+ 'order': undefined,
521
+ 'type': 'limit',
522
+ 'side': side,
523
+ 'takerOrMaker': undefined,
524
+ 'price': priceString,
525
+ 'amount': amountString,
526
+ 'cost': undefined,
527
+ 'fee': undefined,
528
+ 'info': trade,
529
+ }, market);
530
+ }
531
+
532
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
533
+ await this.loadMarkets ();
534
+ const market = this.market (symbol);
535
+ const request = {
536
+ 'marketId': market['id'],
537
+ };
538
+ if (limit !== undefined) {
539
+ request['dataSize'] = limit; // max 20
540
+ }
541
+ const response = await this.publicGetApiDataV1Trades (this.extend (request, params));
542
+ //
543
+ // {
544
+ // "datas": [
545
+ // [
546
+ // "T", // trade
547
+ // "281", // market id
548
+ // "1569303302", // timestamp
549
+ // "BTC_USDT", // market name
550
+ // "ask", // side
551
+ // "9745.08", // price
552
+ // "0.0026" // amount
553
+ // ],
554
+ // ],
555
+ // "resMsg": { "code": "1", "method": null, "message": "success !" },
556
+ // }
557
+ //
558
+ const trades = this.safeValue (response, 'datas', []);
559
+ return this.parseTrades (trades, market, since, limit);
560
+ }
561
+
562
+ async fetchTradingFees (params = {}) {
563
+ await this.loadMarkets ();
564
+ const response = await this.publicGetExchangeConfigControllerWebsiteMarketcontrollerGetByWebId ();
565
+ //
566
+ // {
567
+ // resMsg: { method: null, code: '1', message: 'success !' },
568
+ // datas: [
569
+ // {
570
+ // leverMultiple: '10',
571
+ // amountDecimal: '4',
572
+ // minAmount: '0.0100000000',
573
+ // modifyUid: null,
574
+ // buyerCurrencyId: '11',
575
+ // isCombine: '0',
576
+ // priceDecimal: '3',
577
+ // combineMarketId: '',
578
+ // openPrice: '0',
579
+ // leverEnable: true,
580
+ // marketId: '291',
581
+ // serverId: 'entrust_bw_2',
582
+ // isMining: '0',
583
+ // webId: '102',
584
+ // modifyTime: '1581595375498',
585
+ // defaultFee: '0.00200000',
586
+ // sellerCurrencyId: '7',
587
+ // createTime: '0',
588
+ // state: '1',
589
+ // name: 'eos_usdt',
590
+ // leverType: '2',
591
+ // createUid: null,
592
+ // orderNum: null,
593
+ // openTime: '1574956800000'
594
+ // },
595
+ // ...
596
+ // ]
597
+ // }
598
+ //
599
+ const datas = this.safeValue (response, 'datas', []);
600
+ const result = {};
601
+ for (let i = 0; i < datas.length; i++) {
602
+ const data = datas[i];
603
+ const marketId = this.safeString (data, 'name');
604
+ const symbol = this.safeSymbol (marketId, undefined, '_');
605
+ const fee = this.safeNumber (data, 'defaultFee');
606
+ result[symbol] = {
607
+ 'info': data,
608
+ 'symbol': symbol,
609
+ 'maker': fee,
610
+ 'taker': fee,
611
+ 'percentage': true,
612
+ 'tierBased': true,
613
+ };
614
+ }
615
+ return result;
616
+ }
617
+
618
+ parseOHLCV (ohlcv, market = undefined) {
619
+ //
620
+ // [
621
+ // "K",
622
+ // "305",
623
+ // "eth_btc",
624
+ // "1591511280",
625
+ // "0.02504",
626
+ // "0.02504",
627
+ // "0.02504",
628
+ // "0.02504",
629
+ // "0.0123",
630
+ // "0",
631
+ // "285740.17",
632
+ // "1M",
633
+ // "false",
634
+ // "0.000308"
635
+ // ]
636
+ //
637
+ return [
638
+ this.safeTimestamp (ohlcv, 3),
639
+ this.safeNumber (ohlcv, 4),
640
+ this.safeNumber (ohlcv, 5),
641
+ this.safeNumber (ohlcv, 6),
642
+ this.safeNumber (ohlcv, 7),
643
+ this.safeNumber (ohlcv, 8),
644
+ ];
645
+ }
646
+
647
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
648
+ await this.loadMarkets ();
649
+ const market = this.market (symbol);
650
+ const request = {
651
+ 'marketId': market['id'],
652
+ 'type': this.timeframes[timeframe],
653
+ 'dataSize': 500,
654
+ };
655
+ if (limit !== undefined) {
656
+ request['dataSize'] = limit;
657
+ }
658
+ const response = await this.publicGetApiDataV1Klines (this.extend (request, params));
659
+ //
660
+ // {
661
+ // "datas":[
662
+ // ["K","305","eth_btc","1591511280","0.02504","0.02504","0.02504","0.02504","0.0123","0","285740.17","1M","false","0.000308"],
663
+ // ["K","305","eth_btc","1591511220","0.02504","0.02504","0.02504","0.02504","0.0006","0","285740.17","1M","false","0.00001502"],
664
+ // ["K","305","eth_btc","1591511100","0.02505","0.02505","0.02504","0.02504","0.0012","-0.0399","285740.17","1M","false","0.00003005"],
665
+ // ],
666
+ // "resMsg":{"code":"1","method":null,"message":"success !"}
667
+ // }
668
+ //
669
+ const data = this.safeValue (response, 'datas', []);
670
+ return this.parseOHLCVs (data, market, timeframe, since, limit);
671
+ }
672
+
673
+ parseBalance (response) {
674
+ const data = this.safeValue (response, 'datas', {});
675
+ const balances = this.safeValue (data, 'list', []);
676
+ const result = { 'info': response };
677
+ for (let i = 0; i < balances.length; i++) {
678
+ const balance = balances[i];
679
+ const currencyId = this.safeString (balance, 'currencyTypeId');
680
+ const code = this.safeCurrencyCode (currencyId);
681
+ const account = this.account ();
682
+ account['free'] = this.safeString (balance, 'amount');
683
+ account['used'] = this.safeString (balance, 'freeze');
684
+ result[code] = account;
685
+ }
686
+ return this.safeBalance (result);
687
+ }
688
+
689
+ async fetchBalance (params = {}) {
690
+ await this.loadMarkets ();
691
+ const response = await this.privatePostExchangeFundControllerWebsiteFundcontrollerFindbypage (params);
692
+ //
693
+ // {
694
+ // "datas": {
695
+ // "totalRow": 6,
696
+ // "pageSize": 99,
697
+ // "list": [
698
+ // {
699
+ // "amount": "0.000090000000000000", // The current number of tokens available
700
+ // "currencyTypeId": 2, // Token ID
701
+ // "freeze": "0.009900000000000000", // Current token freezing quantity
702
+ // },
703
+ // ],
704
+ // "pageNum": 1,
705
+ // },
706
+ // "resMsg": { "code": "1", "message": "success !" }
707
+ // }
708
+ //
709
+ return this.parseBalance (response);
710
+ }
711
+
712
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
713
+ if (price === undefined) {
714
+ throw new ExchangeError (this.id + ' createOrder() allows limit orders only');
715
+ }
716
+ await this.loadMarkets ();
717
+ const market = this.market (symbol);
718
+ const request = {
719
+ 'amount': this.amountToPrecision (symbol, amount),
720
+ 'price': this.priceToPrecision (symbol, price),
721
+ 'type': (side === 'buy') ? 1 : 0,
722
+ 'rangeType': 0, // limit order
723
+ 'marketId': market['id'],
724
+ };
725
+ const response = await this.privatePostExchangeEntrustControllerWebsiteEntrustControllerAddEntrust (this.extend (request, params));
726
+ //
727
+ // {
728
+ // "datas": {
729
+ // "entrustId": "E6581105708337483776",
730
+ // },
731
+ // "resMsg": {
732
+ // "message": "success !",
733
+ // "method": null,
734
+ // "code": "1"
735
+ // }
736
+ // }
737
+ //
738
+ const data = this.safeValue (response, 'datas');
739
+ const id = this.safeString (data, 'entrustId');
740
+ return {
741
+ 'id': id,
742
+ 'info': response,
743
+ 'timestamp': undefined,
744
+ 'datetime': undefined,
745
+ 'lastTradeTimestamp': undefined,
746
+ 'symbol': symbol,
747
+ 'type': type,
748
+ 'side': side,
749
+ 'price': price,
750
+ 'amount': amount,
751
+ 'cost': undefined,
752
+ 'average': undefined,
753
+ 'filled': undefined,
754
+ 'remaining': undefined,
755
+ 'status': 'open',
756
+ 'fee': undefined,
757
+ 'trades': undefined,
758
+ 'clientOrderId': undefined,
759
+ };
760
+ }
761
+
762
+ parseOrderStatus (status) {
763
+ const statuses = {
764
+ '-3': 'canceled',
765
+ '-2': 'canceled',
766
+ '-1': 'canceled',
767
+ '0': 'open',
768
+ '1': 'canceled',
769
+ '2': 'closed',
770
+ '3': 'open',
771
+ '4': 'canceled',
772
+ };
773
+ return this.safeString (statuses, status, status);
774
+ }
775
+
776
+ parseOrder (order, market = undefined) {
777
+ //
778
+ // fetchOrder, fetchOpenOrders, fetchClosedOrders
779
+ //
780
+ // {
781
+ // "entrustId": "E6581108027628212224", // Order id
782
+ // "price": "1450", // price
783
+ // "rangeType": 0, // Commission type 0: limit price commission 1: interval commission
784
+ // "amount": "14.05", // Order quantity
785
+ // "totalMoney": "20372.50", // Total order amount
786
+ // "completeAmount": "0", // Quantity sold
787
+ // "completeTotalMoney": "0", // Total dealt amount
788
+ // "type": 1, // 0 = sell, 1 = buy, -1 = cancel
789
+ // "entrustType": 0, // 0 = ordinary current price commission, 1 = lever commission
790
+ // "status": 0, //
791
+ // "marketId": "318", // The market id
792
+ // "createTime": 1569058424861, // Create time
793
+ // "availabelAmount": "14.05" // Outstanding quantity, typo in the docs or in the API, availabel vs available
794
+ // }
795
+ //
796
+ const marketId = this.safeString (order, 'marketId');
797
+ const symbol = this.safeSymbol (marketId, market);
798
+ const timestamp = this.safeInteger (order, 'createTime');
799
+ let side = this.safeString (order, 'type');
800
+ if (side === '0') {
801
+ side = 'sell';
802
+ } else if (side === '1') {
803
+ side = 'buy';
804
+ }
805
+ const amount = this.safeString (order, 'amount');
806
+ const price = this.safeString (order, 'price');
807
+ const filled = this.safeString (order, 'completeAmount');
808
+ const remaining = this.safeString2 (order, 'availabelAmount', 'availableAmount'); // typo in the docs or in the API, availabel vs available
809
+ const cost = this.safeString (order, 'totalMoney');
810
+ const status = this.parseOrderStatus (this.safeString (order, 'status'));
811
+ return this.safeOrder ({
812
+ 'info': order,
813
+ 'id': this.safeString (order, 'entrustId'),
814
+ 'clientOrderId': undefined,
815
+ 'timestamp': timestamp,
816
+ 'datetime': this.iso8601 (timestamp),
817
+ 'lastTradeTimestamp': undefined,
818
+ 'symbol': symbol,
819
+ 'type': 'limit',
820
+ 'timeInForce': undefined,
821
+ 'postOnly': undefined,
822
+ 'side': side,
823
+ 'price': price,
824
+ 'stopPrice': undefined,
825
+ 'amount': amount,
826
+ 'cost': cost,
827
+ 'average': undefined,
828
+ 'filled': filled,
829
+ 'remaining': remaining,
830
+ 'status': status,
831
+ 'fee': undefined,
832
+ 'trades': undefined,
833
+ }, market);
834
+ }
835
+
836
+ async fetchOrder (id, symbol = undefined, params = {}) {
837
+ if (symbol === undefined) {
838
+ throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument');
839
+ }
840
+ await this.loadMarkets ();
841
+ const market = this.market (symbol);
842
+ const request = {
843
+ 'marketId': market['id'],
844
+ 'entrustId': id,
845
+ };
846
+ const response = await this.privateGetExchangeEntrustControllerWebsiteEntrustControllerGetEntrustById (this.extend (request, params));
847
+ //
848
+ // {
849
+ // "datas": {
850
+ // "entrustId": "E6581108027628212224", // Order id
851
+ // "price": "1450", // price
852
+ // "rangeType": 0, // Commission type 0: limit price commission 1: interval commission
853
+ // "amount": "14.05", // Order quantity
854
+ // "totalMoney": "20372.50", // Total order amount
855
+ // "completeAmount": "0", // Quantity sold
856
+ // "completeTotalMoney": "0", // Total dealt amount
857
+ // "type": 1, // Trade direction, 0: sell, 1: buy, -1: cancel
858
+ // "entrustType": 0, // Commission type, 0: ordinary current price commission, 1: lever commission
859
+ // "status": 0, // Order status,-3:fund Freeze exception,Order status to be confirmed -2: fund freeze failure, order failure, -1: insufficient funds, order failure, 0: pending order, 1: cancelled, 2: dealt, 3: partially dealt
860
+ // "marketId": "318", // The market id
861
+ // "createTime": 1569058424861, // Create time
862
+ // "availabelAmount": "14.05" // Outstanding quantity
863
+ // },
864
+ // "resMsg": { "message": "success !", "method": null, "code": "1" }
865
+ // }
866
+ //
867
+ const order = this.safeValue (response, 'datas', {});
868
+ return this.parseOrder (order, market);
869
+ }
870
+
871
+ async cancelOrder (id, symbol = undefined, params = {}) {
872
+ if (symbol === undefined) {
873
+ throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
874
+ }
875
+ await this.loadMarkets ();
876
+ const market = this.market (symbol);
877
+ const request = {
878
+ 'marketId': market['id'],
879
+ 'entrustId': id,
880
+ };
881
+ const response = await this.privatePostExchangeEntrustControllerWebsiteEntrustControllerCancelEntrust (this.extend (request, params));
882
+ //
883
+ // {
884
+ // "datas": null,
885
+ // "resMsg": { "message": "success !", "method": null, "code": "1" }
886
+ // }
887
+ //
888
+ return {
889
+ 'info': response,
890
+ 'id': id,
891
+ };
892
+ }
893
+
894
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
895
+ if (symbol === undefined) {
896
+ throw new ArgumentsRequired (this.id + ' fetchOpenOrders() requires a symbol argument');
897
+ }
898
+ await this.loadMarkets ();
899
+ const market = this.market (symbol);
900
+ const request = {
901
+ 'marketId': market['id'],
902
+ // 'pageSize': limit, // documented as required, but it works without it
903
+ // 'pageIndex': 0, // also works without it, most likely a typo in the docs
904
+ };
905
+ if (limit !== undefined) {
906
+ request['pageSize'] = limit; // default limit is 20
907
+ }
908
+ const response = await this.privateGetExchangeEntrustControllerWebsiteEntrustControllerGetUserEntrustRecordFromCacheWithPage (this.extend (request, params));
909
+ //
910
+ // {
911
+ // "datas": {
912
+ // "pageNum": 1,
913
+ // "pageSize": 2,
914
+ // "totalPage": 20,
915
+ // "totalRow": 40,
916
+ // "entrustList": [
917
+ // {
918
+ // "amount": "14.050000000000000000", // Order quantity
919
+ // "rangeType": 0, // Commission type 0: limit price commission 1: interval commission
920
+ // "totalMoney": "20372.500000000000000000", // Total order amount
921
+ // "entrustId": "E6581108027628212224", // Order id
922
+ // "type": 1, // Trade direction, 0: sell, 1: buy, -1: cancel
923
+ // "completeAmount": "0", // Quantity sold
924
+ // "marketId": "318", // The market id
925
+ // "createTime": 1569058424861, // Create time
926
+ // "price": "1450.000000000", // price
927
+ // "completeTotalMoney": "0", // Quantity sold
928
+ // "entrustType": 0, // Commission type, 0: ordinary current price commission, 1: lever commission
929
+ // "status": 0 // Order status,-3:fund Freeze exception,Order status to be confirmed -2: fund freeze failure, order failure, -1: insufficient funds, order failure, 0: pending order, 1: cancelled, 2: dealt, 3: partially dealt
930
+ // },
931
+ // ],
932
+ // },
933
+ // "resMsg": { "message": "success !", "method": null, "code": "1" },
934
+ // }
935
+ //
936
+ const data = this.safeValue (response, 'datas', {});
937
+ const orders = this.safeValue (data, 'entrustList', []);
938
+ return this.parseOrders (orders, market, since, limit);
939
+ }
940
+
941
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
942
+ if (symbol === undefined) {
943
+ throw new ArgumentsRequired (this.id + ' fetchClosedOrders() requires a symbol argument');
944
+ }
945
+ await this.loadMarkets ();
946
+ const market = this.market (symbol);
947
+ const request = {
948
+ 'marketId': market['id'],
949
+ };
950
+ if (limit !== undefined) {
951
+ request['pageSize'] = limit; // default limit is 20
952
+ }
953
+ if (since !== undefined) {
954
+ request['startDateTime'] = since;
955
+ }
956
+ const response = await this.privateGetExchangeEntrustControllerWebsiteEntrustControllerGetUserEntrustList (this.extend (request, params));
957
+ const data = this.safeValue (response, 'datas', {});
958
+ const orders = this.safeValue (data, 'entrustList', []);
959
+ return this.parseOrders (orders, market, since, limit);
960
+ }
961
+
962
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
963
+ if (symbol === undefined) {
964
+ throw new ArgumentsRequired (this.id + ' fetchOpenOrders() requires a symbol argument');
965
+ }
966
+ await this.loadMarkets ();
967
+ const market = this.market (symbol);
968
+ const request = {
969
+ 'marketId': market['id'],
970
+ // 'pageSize': limit, // documented as required, but it works without it
971
+ // 'pageIndex': 0, // also works without it, most likely a typo in the docs
972
+ // 'type': 0, // 0 = sell, 1 = buy, -1 = cancel
973
+ // 'status': -1, // -1 = insufficient funds, failed orders, 0 = pending orders, 1 = canceled, 2 = closed, 3 = partial
974
+ // 'startDateTime': since,
975
+ // 'endDateTime': this.milliseconds (),
976
+ };
977
+ if (since !== undefined) {
978
+ request['startDateTime'] = since;
979
+ }
980
+ if (limit !== undefined) {
981
+ request['pageSize'] = limit; // default limit is 20
982
+ }
983
+ const response = await this.privateGetExchangeEntrustControllerWebsiteEntrustControllerGetUserEntrustList (this.extend (request, params));
984
+ //
985
+ // {
986
+ // "datas": {
987
+ // "pageNum": 1,
988
+ // "pageSize": 2,
989
+ // "totalPage": 20,
990
+ // "totalRow": 40,
991
+ // "entrustList": [
992
+ // {
993
+ // "amount": "14.050000000000000000", // Order quantity
994
+ // "rangeType": 0, // Commission type 0: limit price commission 1: interval commission
995
+ // "totalMoney": "20372.500000000000000000", // Total order amount
996
+ // "entrustId": "E6581108027628212224", // Order id
997
+ // "type": 1, // Trade direction, 0: sell, 1: buy, -1: cancel
998
+ // "completeAmount": "0", // Quantity sold
999
+ // "marketId": "318", // The market id
1000
+ // "createTime": 1569058424861, // Create time
1001
+ // "price": "1450.000000000", // price
1002
+ // "completeTotalMoney": "0", // Quantity sold
1003
+ // "entrustType": 0, // Commission type, 0: ordinary current price commission, 1: lever commission
1004
+ // "status": 0 // Order status,-3:fund Freeze exception,Order status to be confirmed -2: fund freeze failure, order failure, -1: insufficient funds, order failure, 0: pending order, 1: cancelled, 2: dealt, 3: partially dealt
1005
+ // },
1006
+ // ],
1007
+ // },
1008
+ // "resMsg": { "message": "success !", "method": null, "code": "1" },
1009
+ // }
1010
+ //
1011
+ const data = this.safeValue (response, 'datas', {});
1012
+ const orders = this.safeValue (data, 'entrustList', []);
1013
+ return this.parseOrders (orders, market, since, limit);
1014
+ }
1015
+
1016
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1017
+ let url = this.implodeHostname (this.urls['api']) + '/' + path;
1018
+ if (method === 'GET') {
1019
+ if (Object.keys (params).length) {
1020
+ url += '?' + this.urlencode (params);
1021
+ }
1022
+ } else {
1023
+ body = this.json (params);
1024
+ }
1025
+ if (api === 'private') {
1026
+ const ms = this.milliseconds ().toString ();
1027
+ let content = '';
1028
+ if (method === 'GET') {
1029
+ const sortedParams = this.keysort (params);
1030
+ const keys = Object.keys (sortedParams);
1031
+ for (let i = 0; i < keys.length; i++) {
1032
+ const key = keys[i];
1033
+ content += key + sortedParams[key].toString ();
1034
+ }
1035
+ } else {
1036
+ content = body;
1037
+ }
1038
+ const signature = this.apiKey + ms + content + this.secret;
1039
+ const hash = this.hash (this.encode (signature), 'md5');
1040
+ if (!headers) {
1041
+ headers = {};
1042
+ }
1043
+ headers['Apiid'] = this.apiKey;
1044
+ headers['Timestamp'] = ms;
1045
+ headers['Sign'] = hash;
1046
+ }
1047
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1048
+ }
1049
+
1050
+ async fetchDepositAddress (code, params = {}) {
1051
+ await this.loadMarkets ();
1052
+ const currency = this.currency (code);
1053
+ const request = {
1054
+ 'currencyTypeName': currency['name'],
1055
+ };
1056
+ const response = await this.privatePostExchangeFundControllerWebsiteFundcontrollerGetPayinAddress (this.extend (request, params));
1057
+ //
1058
+ // {
1059
+ // "datas": {
1060
+ // "isMemo": true, // 是否为memo 格式,false:否,true :是
1061
+ // "address": "bweosdeposit_787928102918558272", // 充币地址
1062
+ // "memo": "787928102918558272", // 币种memo
1063
+ // "account": "bweosdeposit" // 币种账户
1064
+ // },
1065
+ // "resMsg": { "message": "success !", "method": null, "code": "1" }
1066
+ // }
1067
+ //
1068
+ const data = this.safeValue (response, 'datas', {});
1069
+ const address = this.safeString (data, 'address');
1070
+ const tag = this.safeString (data, 'memo');
1071
+ this.checkAddress (address);
1072
+ return {
1073
+ 'currency': code,
1074
+ 'address': this.checkAddress (address),
1075
+ 'tag': tag,
1076
+ 'network': undefined,
1077
+ 'info': response,
1078
+ };
1079
+ }
1080
+
1081
+ parseTransactionStatus (status) {
1082
+ const statuses = {
1083
+ '-1': 'canceled', // or auditing failed
1084
+ '0': 'pending',
1085
+ '1': 'ok',
1086
+ };
1087
+ return this.safeString (statuses, status, status);
1088
+ }
1089
+
1090
+ parseTransaction (transaction, currency = undefined) {
1091
+ //
1092
+ // fetchDeposits
1093
+ //
1094
+ // {
1095
+ // "depositId": "D6574268549744189441", // Deposit ID
1096
+ // "amount": "54.753589700000000000", // Deposit amount
1097
+ // "txId": "INNER_SYSTEM_TRANSFER_1198941", // Trading ID
1098
+ // "confirmTimes": 0, // Confirmation number
1099
+ // "depositAddress": "bweosdeposit_787928102918558272", // Deposit address
1100
+ // "createTime": "2019-09-02 20:36:08.0", // Deposit time
1101
+ // "status": 1, // Deposit status, 0: not received, 1: received
1102
+ // "currencyTypeId": 7, // Token ID
1103
+ // }
1104
+ //
1105
+ // fetchWithdrawals
1106
+ //
1107
+ // {
1108
+ // "withdrawalId": "W6527498439872634880", // Withdrawal ID
1109
+ // "fees": "0.500000000000000000", // Withdrawal fee
1110
+ // "withdrawalAddress": "okbtothemoon_941657", // Withdrawal address
1111
+ // "currencyId": "7", // Token ID
1112
+ // "amount": "10.000000000000000000", // Withdrawal amount
1113
+ // "state": 1, // Status, 1: normal, -1: delete
1114
+ // "verifyStatus": 1, // Audit status, 0: to be audited, 1: auditing passed, -1: auditing failed
1115
+ // "createTime": 1556276903656, // WIthdrawal time
1116
+ // "actuallyAmount": "9.500000000000000000", // Actual amount received
1117
+ // }
1118
+ //
1119
+ const id = this.safeString (transaction, 'depositId', 'withdrawalId');
1120
+ const address = this.safeString2 (transaction, 'depositAddress', 'withdrawalAddress');
1121
+ const currencyId = this.safeString2 (transaction, 'currencyId', 'currencyTypeId');
1122
+ let code = undefined;
1123
+ if (currencyId in this.currencies_by_id) {
1124
+ currency = this.currencies_by_id[currencyId];
1125
+ }
1126
+ if ((code === undefined) && (currency !== undefined)) {
1127
+ code = currency['code'];
1128
+ }
1129
+ const type = ('depositId' in transaction) ? 'deposit' : 'withdrawal';
1130
+ const amount = this.safeNumber2 (transaction, 'actuallyAmount', 'amount');
1131
+ const status = this.parseTransactionStatus (this.safeString2 (transaction, 'verifyStatus', 'state'));
1132
+ const timestamp = this.safeInteger (transaction, 'createTime');
1133
+ const txid = this.safeString (transaction, 'txId');
1134
+ let fee = undefined;
1135
+ const feeCost = this.safeNumber (transaction, 'fees');
1136
+ if (feeCost !== undefined) {
1137
+ fee = {
1138
+ 'cost': feeCost,
1139
+ 'currency': code,
1140
+ };
1141
+ }
1142
+ return {
1143
+ 'info': transaction,
1144
+ 'id': id,
1145
+ 'txid': txid,
1146
+ 'timestamp': timestamp,
1147
+ 'datetime': this.iso8601 (timestamp),
1148
+ 'network': undefined,
1149
+ 'addressFrom': undefined,
1150
+ 'address': address,
1151
+ 'addressTo': undefined,
1152
+ 'tagFrom': undefined,
1153
+ 'tag': undefined,
1154
+ 'tagTo': undefined,
1155
+ 'type': type,
1156
+ 'amount': amount,
1157
+ 'currency': code,
1158
+ 'status': status,
1159
+ 'updated': undefined,
1160
+ 'fee': fee,
1161
+ };
1162
+ }
1163
+
1164
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1165
+ if (code === undefined) {
1166
+ throw new ArgumentsRequired (this.id + ' fetchDeposits() requires a currency code argument');
1167
+ }
1168
+ await this.loadMarkets ();
1169
+ const currency = this.currency (code);
1170
+ const request = {
1171
+ 'currencyTypeName': currency['name'],
1172
+ // 'pageSize': limit, // documented as required, but it works without it
1173
+ // 'pageNum': 0, // also works without it, most likely a typo in the docs
1174
+ // 'sort': 1, // 1 = asc, 0 = desc
1175
+ };
1176
+ if (limit !== undefined) {
1177
+ request['pageSize'] = limit; // default 50
1178
+ }
1179
+ const response = await this.privatePostExchangeFundControllerWebsiteFundcontrollerGetPayinCoinRecord (this.extend (request, params));
1180
+ //
1181
+ // {
1182
+ // "datas": {
1183
+ // "totalRow":2,
1184
+ // "totalPage": 1,
1185
+ // "pageSize": 2,
1186
+ // "pageNum": 1,
1187
+ // "list": [
1188
+ // {
1189
+ // "depositId": "D6574268549744189441", // Deposit ID
1190
+ // "amount": "54.753589700000000000", // Deposit amount
1191
+ // "txId": "INNER_SYSTEM_TRANSFER_1198941", // Trading ID
1192
+ // "confirmTimes": 0, // Confirmation number
1193
+ // "depositAddress": "bweosdeposit_787928102918558272", // Deposit address
1194
+ // "createTime": "2019-09-02 20:36:08.0", // Deposit time
1195
+ // "status": 1, // Deposit status, 0: not received, 1: received
1196
+ // "currencyTypeId": 7, // Token ID
1197
+ // },
1198
+ // ]
1199
+ // },
1200
+ // "resMsg": { "message": "success !", "method": null, "code": "1" },
1201
+ // }
1202
+ //
1203
+ const data = this.safeValue (response, 'datas', {});
1204
+ const deposits = this.safeValue (data, 'list', []);
1205
+ return this.parseTransactions (deposits, code, since, limit);
1206
+ }
1207
+
1208
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1209
+ if (code === undefined) {
1210
+ throw new ArgumentsRequired (this.id + ' fetchWithdrawals() requires a currency code argument');
1211
+ }
1212
+ await this.loadMarkets ();
1213
+ const currency = this.currency (code);
1214
+ const request = {
1215
+ 'currencyId': currency['id'],
1216
+ // 'pageSize': limit, // documented as required, but it works without it
1217
+ // 'pageIndex': 0, // also works without it, most likely a typo in the docs
1218
+ // 'tab': 'all', // all, wait (submitted, not audited), success (auditing passed), fail (auditing failed), cancel (canceled by user)
1219
+ };
1220
+ if (limit !== undefined) {
1221
+ request['pageSize'] = limit; // default 50
1222
+ }
1223
+ const response = await this.privateGetExchangeFundControllerWebsiteFundwebsitecontrollerGetpayoutcoinrecord (this.extend (request, params));
1224
+ //
1225
+ // {
1226
+ // "datas": {
1227
+ // "totalRow": 1,
1228
+ // "totalPage": 1,
1229
+ // "pageSize": 2,
1230
+ // "pageNum": 1,
1231
+ // "list": [
1232
+ // {
1233
+ // "withdrawalId": "W6527498439872634880", // Withdrawal ID
1234
+ // "fees": "0.500000000000000000", // Withdrawal fee
1235
+ // "withdrawalAddress": "okbtothemoon_941657", // Withdrawal address
1236
+ // "currencyId": "7", // Token ID
1237
+ // "amount": "10.000000000000000000", // Withdrawal amount
1238
+ // "state": 1, // Status, 1: normal, -1: delete
1239
+ // "verifyStatus": 1, // Audit status, 0: to be audited, 1: auditing passed, -1: auditing failed
1240
+ // "createTime": 1556276903656, // WIthdrawal time
1241
+ // "actuallyAmount": "9.500000000000000000", // Actual amount received
1242
+ // },
1243
+ // ],
1244
+ // },
1245
+ // "resMsg": { "message": "success !", "method": null, "code": "1" },
1246
+ // }
1247
+ //
1248
+ const data = this.safeValue (response, 'datas', {});
1249
+ const withdrawals = this.safeValue (data, 'list', []);
1250
+ return this.parseTransactions (withdrawals, code, since, limit);
1251
+ }
1252
+
1253
+ handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1254
+ if (!response) {
1255
+ return; // default error handler
1256
+ }
1257
+ const resMsg = this.safeValue (response, 'resMsg');
1258
+ const errorCode = this.safeString (resMsg, 'code');
1259
+ if (errorCode !== '1') {
1260
+ const feedback = this.id + ' ' + this.json (response);
1261
+ this.throwExactlyMatchedException (this.exceptions['exact'], errorCode, feedback);
1262
+ throw new ExchangeError (feedback); // unknown error
1263
+ }
1264
+ }
1265
+ };