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/eqonex.js ADDED
@@ -0,0 +1,1660 @@
1
+ 'use strict';
2
+
3
+ // ----------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, ArgumentsRequired, BadSymbol } = require ('./base/errors');
7
+ const Precise = require ('./base/Precise');
8
+
9
+ // ----------------------------------------------------------------------------
10
+
11
+ module.exports = class eqonex extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'eqonex',
15
+ 'name': 'EQONEX',
16
+ 'countries': [ 'US', 'SG' ], // United States, Singapore
17
+ 'rateLimit': 10,
18
+ 'has': {
19
+ 'CORS': undefined,
20
+ 'spot': true,
21
+ 'margin': false,
22
+ 'swap': undefined, // has but not fully implemented
23
+ 'future': undefined, // has but not fully implemented
24
+ 'option': false,
25
+ 'cancelOrder': true,
26
+ 'createOrder': true,
27
+ 'createStopLimitOrder': true,
28
+ 'createStopMarketOrder': true,
29
+ 'createStopOrder': true,
30
+ 'editOrder': true,
31
+ 'fetchBalance': true,
32
+ 'fetchBorrowRate': false,
33
+ 'fetchBorrowRateHistories': false,
34
+ 'fetchBorrowRateHistory': false,
35
+ 'fetchBorrowRates': false,
36
+ 'fetchBorrowRatesPerSymbol': false,
37
+ 'fetchCanceledOrders': true,
38
+ 'fetchClosedOrders': true,
39
+ 'fetchCurrencies': true,
40
+ 'fetchDepositAddress': true,
41
+ 'fetchDeposits': true,
42
+ 'fetchMarkets': true,
43
+ 'fetchMyTrades': true,
44
+ 'fetchOHLCV': true,
45
+ 'fetchOrder': true,
46
+ 'fetchOrderBook': true,
47
+ 'fetchOrders': true,
48
+ 'fetchTicker': undefined,
49
+ 'fetchTrades': true,
50
+ 'fetchTradingFee': false,
51
+ 'fetchTradingFees': true,
52
+ 'fetchTradingLimits': true,
53
+ 'fetchWithdrawals': true,
54
+ 'withdraw': true,
55
+ },
56
+ 'timeframes': {
57
+ '1m': 1,
58
+ '5m': 2,
59
+ '15m': 3,
60
+ '1h': 4,
61
+ '6h': 5,
62
+ '1d': 6,
63
+ '7d': 7,
64
+ '1w': 7,
65
+ },
66
+ 'urls': {
67
+ 'logo': 'https://user-images.githubusercontent.com/51840849/122649755-1a076c80-d138-11eb-8f2e-9a9166a03d79.jpg',
68
+ 'test': {
69
+ 'public': 'https://testnet.eqonex.com/api',
70
+ 'private': 'https://testnet.eqonex.com/api',
71
+ },
72
+ 'api': {
73
+ 'public': 'https://eqonex.com/api',
74
+ 'private': 'https://eqonex.com/api',
75
+ },
76
+ 'www': 'https://eqonex.com',
77
+ 'doc': [
78
+ 'https://developer.eqonex.com',
79
+ ],
80
+ 'referral': 'https://eqonex.com?referredByCode=zpa8kij4ouvBFup3',
81
+ },
82
+ 'api': {
83
+ 'public': {
84
+ 'get': [
85
+ 'health',
86
+ 'getInstruments',
87
+ 'getInstrumentPairs',
88
+ 'getOrderBook',
89
+ 'getRisk',
90
+ 'getTradeHistory',
91
+ 'getFundingRateHistory',
92
+ 'getChart',
93
+ 'getExchangeInfo', // not documented
94
+ ],
95
+ },
96
+ 'private': {
97
+ 'post': [
98
+ 'logon',
99
+ 'order',
100
+ 'cancelOrder',
101
+ 'cancelReplaceOrder',
102
+ 'getOrder',
103
+ 'getOrders',
104
+ 'getOrderStatus',
105
+ 'getOrderHistory',
106
+ 'userTrades',
107
+ 'getPositions',
108
+ 'cancelAll',
109
+ 'getUserHistory',
110
+ 'getRisk',
111
+ 'getDepositAddresses',
112
+ 'getDepositHistory', // not documented
113
+ 'getWithdrawRequests',
114
+ 'sendWithdrawRequest',
115
+ 'getTransferHistory',
116
+ ],
117
+ },
118
+ },
119
+ 'requiredCredentials': {
120
+ 'apiKey': true,
121
+ 'secret': true,
122
+ 'uid': true,
123
+ },
124
+ 'exceptions': {
125
+ 'broad': {
126
+ 'symbol not found': BadSymbol,
127
+ },
128
+ },
129
+ });
130
+ }
131
+
132
+ async fetchMarkets (params = {}) {
133
+ const request = {
134
+ 'verbose': true,
135
+ };
136
+ const response = await this.publicGetGetInstrumentPairs (this.extend (request, params));
137
+ //
138
+ // {
139
+ // "instrumentPairs": [
140
+ // {
141
+ // "instrumentId":303,
142
+ // "symbol":"BTC/USDC[220325]",
143
+ // "quoteId":1,
144
+ // "baseId":3,
145
+ // "price_scale":2,
146
+ // "quantity_scale":6,
147
+ // "securityStatus":1,
148
+ // "securityDesc":"BTC Dated Future",
149
+ // "assetType":"DATED_FUTURE",
150
+ // "currency":"BTC",
151
+ // "contAmtCurr":"USDC",
152
+ // "settlCurrency":"USDC",
153
+ // "commCurrency":"USDC",
154
+ // "cfiCode":"FFCPSX",
155
+ // "securityExchange":"EQOS",
156
+ // "micCode":"EQOD",
157
+ // "instrumentPricePrecision":2,
158
+ // "minPriceIncrement":1.0,
159
+ // "minPriceIncrementAmount":1.0,
160
+ // "roundLot":100,
161
+ // "minTradeVol":0.000100,
162
+ // "maxTradeVol":0.000000,
163
+ // "qtyType":0,
164
+ // "contractMultiplier":1.0,
165
+ // "auctionStartTime":0,
166
+ // "auctionDuration":0,
167
+ // "auctionFrequency":0,
168
+ // "auctionPrice":0,
169
+ // "auctionVolume":0,
170
+ // "marketStatus":"OPEN",
171
+ // "underlyingSymbol":"BTC/USDC",
172
+ // "underlyingSecurityId":52,
173
+ // "underlyingSecuritySource":"M",
174
+ // "underlyingSecurityExchange":"EQOC",
175
+ // "issueDate":1643256000000,
176
+ // "maturityDate":"2022-03-25",
177
+ // "maturityTime":"2022-03-25T08:00:00Z",
178
+ // "contractExpireTime":1648195200000
179
+ // }
180
+ // ...
181
+ // ]
182
+ // }
183
+ //
184
+ const instrumentPairs = this.safeValue (response, 'instrumentPairs', []);
185
+ const markets = [];
186
+ for (let i = 0; i < instrumentPairs.length; i++) {
187
+ const market = this.parseMarket (instrumentPairs[i]);
188
+ markets.push (market);
189
+ }
190
+ return markets;
191
+ }
192
+
193
+ parseMarket (market) {
194
+ //
195
+ // {
196
+ // "instrumentPairs": [
197
+ // {
198
+ // "instrumentId":303,
199
+ // "symbol":"BTC/USDC[220325]",
200
+ // "quoteId":1,
201
+ // "baseId":3,
202
+ // "price_scale":2,
203
+ // "quantity_scale":6,
204
+ // "securityStatus":1,
205
+ // "securityDesc":"BTC Dated Future",
206
+ // "assetType":"DATED_FUTURE",
207
+ // "currency":"BTC",
208
+ // "contAmtCurr":"USDC",
209
+ // "settlCurrency":"USDC",
210
+ // "commCurrency":"USDC",
211
+ // "cfiCode":"FFCPSX",
212
+ // "securityExchange":"EQOS",
213
+ // "micCode":"EQOD",
214
+ // "instrumentPricePrecision":2,
215
+ // "minPriceIncrement":1.0,
216
+ // "minPriceIncrementAmount":1.0,
217
+ // "roundLot":100,
218
+ // "minTradeVol":0.000100,
219
+ // "maxTradeVol":0.000000,
220
+ // "qtyType":0,
221
+ // "contractMultiplier":1.0,
222
+ // "auctionStartTime":0,
223
+ // "auctionDuration":0,
224
+ // "auctionFrequency":0,
225
+ // "auctionPrice":0,
226
+ // "auctionVolume":0,
227
+ // "marketStatus":"OPEN",
228
+ // "underlyingSymbol":"BTC/USDC",
229
+ // "underlyingSecurityId":52,
230
+ // "underlyingSecuritySource":"M",
231
+ // "underlyingSecurityExchange":"EQOC",
232
+ // "issueDate":1643256000000,
233
+ // "maturityDate":"2022-03-25",
234
+ // "maturityTime":"2022-03-25T08:00:00Z",
235
+ // "contractExpireTime":1648195200000
236
+ // }
237
+ // ...
238
+ // ]
239
+ // }
240
+ //
241
+ const assetType = this.safeString (market, 'assetType');
242
+ const spot = (assetType === 'PAIR');
243
+ const swap = (assetType === 'PERPETUAL_SWAP');
244
+ const future = (assetType === 'DATED_FUTURE');
245
+ const contract = swap || future;
246
+ const id = this.safeString (market, 'instrumentId');
247
+ const baseId = this.safeString (market, 'currency');
248
+ const quoteId = this.safeString (market, 'contAmtCurr');
249
+ const settleId = contract ? this.safeString (market, 'settlCurrency') : undefined;
250
+ const base = this.safeCurrencyCode (baseId);
251
+ const quote = this.safeCurrencyCode (quoteId);
252
+ const settle = this.safeCurrencyCode (settleId);
253
+ let symbol = base + '/' + quote;
254
+ const uppercaseId = this.safeString (market, 'symbol');
255
+ let type = 'spot';
256
+ let linear = undefined;
257
+ let inverse = undefined;
258
+ const expiry = this.safeNumber (market, 'contractExpireTime');
259
+ if (contract) {
260
+ symbol = symbol + ':' + settle;
261
+ linear = (quote === settle);
262
+ inverse = !linear;
263
+ if (swap) {
264
+ type = 'swap';
265
+ } else if (future) {
266
+ symbol = symbol + '-' + this.yymmdd (expiry);
267
+ type = 'future';
268
+ } else {
269
+ symbol = uppercaseId;
270
+ type = assetType;
271
+ }
272
+ }
273
+ const status = this.safeInteger (market, 'securityStatus');
274
+ return {
275
+ 'id': id,
276
+ 'uppercaseId': uppercaseId,
277
+ 'symbol': symbol,
278
+ 'base': base,
279
+ 'quote': quote,
280
+ 'settle': settle,
281
+ 'baseId': baseId,
282
+ 'quoteId': quoteId,
283
+ 'settleId': settleId,
284
+ 'type': type,
285
+ 'spot': spot,
286
+ 'margin': false,
287
+ 'swap': swap,
288
+ 'future': future,
289
+ 'option': false,
290
+ 'active': (status === 1),
291
+ 'contract': contract,
292
+ 'linear': linear,
293
+ 'inverse': inverse,
294
+ 'contractSize': this.safeNumber (market, 'contractMultiplier'),
295
+ 'expiry': expiry,
296
+ 'expiryDatetime': this.iso8601 (expiry),
297
+ 'strike': undefined,
298
+ 'optionType': undefined,
299
+ 'precision': {
300
+ 'amount': this.safeInteger (market, 'quantity_scale'),
301
+ 'price': this.safeInteger (market, 'price_scale'),
302
+ },
303
+ 'limits': {
304
+ 'leverage': {
305
+ 'min': undefined,
306
+ 'max': undefined,
307
+ },
308
+ 'amount': {
309
+ 'min': this.safeNumber (market, 'minTradeVol'),
310
+ 'max': undefined,
311
+ },
312
+ 'price': {
313
+ 'min': undefined,
314
+ 'max': undefined,
315
+ },
316
+ 'cost': {
317
+ 'min': undefined,
318
+ 'max': undefined,
319
+ },
320
+ },
321
+ 'info': market,
322
+ };
323
+ }
324
+
325
+ async fetchCurrencies (params = {}) {
326
+ const response = await this.publicGetGetInstruments (params);
327
+ //
328
+ // {
329
+ // "instruments": [
330
+ // [
331
+ // 3, // id
332
+ // "BTC", // symbol
333
+ // 2, // price_scale
334
+ // 6, // amount_scale
335
+ // 1, // status
336
+ // 0, // withdraw_fee
337
+ // "BTC", // name
338
+ // true, // withdrawal_pct
339
+ // ],
340
+ // ]
341
+ // }
342
+ //
343
+ const currencies = {};
344
+ const instruments = this.safeValue (response, 'instruments', []);
345
+ for (let i = 0; i < instruments.length; i++) {
346
+ const currency = this.parseCurrency (instruments[i]);
347
+ const code = currency['code'];
348
+ currencies[code] = currency;
349
+ }
350
+ return currencies;
351
+ }
352
+
353
+ parseCurrency (currency) {
354
+ //
355
+ // [
356
+ // 3, // 0 id
357
+ // "BTC", // 1 symbol
358
+ // 2, // 2 price_scale
359
+ // 6, // 3 amount_scale
360
+ // 1, // 4 status
361
+ // 0, // 5 withdraw_fee
362
+ // "BTC", // 6 name
363
+ // true, // 7 withdrawal_pct
364
+ // ],
365
+ //
366
+ const id = this.safeString (currency, 0);
367
+ const uppercaseId = this.safeString (currency, 1);
368
+ const code = this.safeCurrencyCode (uppercaseId);
369
+ const priceScale = this.safeInteger (currency, 2);
370
+ const amountScale = this.safeInteger (currency, 3);
371
+ const precision = Math.max (priceScale, amountScale);
372
+ const name = this.safeString (currency, 6);
373
+ const status = this.safeInteger (currency, 4);
374
+ const active = (status === 1);
375
+ const fee = this.safeNumber (currency, 5); // withdraw_fee
376
+ return {
377
+ 'id': id,
378
+ 'info': currency,
379
+ 'uppercaseId': uppercaseId,
380
+ 'code': code,
381
+ 'name': name,
382
+ 'precision': precision,
383
+ 'fee': fee,
384
+ 'active': active,
385
+ 'deposit': undefined,
386
+ 'withdraw': undefined,
387
+ 'limits': {
388
+ 'amount': {
389
+ 'min': undefined,
390
+ 'max': undefined,
391
+ },
392
+ 'withdraw': {
393
+ 'min': undefined,
394
+ 'max': undefined,
395
+ },
396
+ },
397
+ };
398
+ }
399
+
400
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
401
+ await this.loadMarkets ();
402
+ const market = this.market (symbol);
403
+ const request = {
404
+ 'pairId': parseInt (market['id']),
405
+ 'timespan': this.timeframes[timeframe],
406
+ };
407
+ if (limit !== undefined) {
408
+ request['limit'] = limit;
409
+ }
410
+ const response = await this.publicGetGetChart (this.extend (request, params));
411
+ //
412
+ // {
413
+ // "pairId":57,
414
+ // "t":1,
415
+ // "s":"ETH/BTC",
416
+ // "lastPx":44099,
417
+ // "lastQty":100000,
418
+ // "o":0.043831000000000016,
419
+ // "h":0.04427100000000002,
420
+ // "l":0.032000000000000015,
421
+ // "c":0.04409900000000002,
422
+ // "v":0.21267333000000016,
423
+ // "q":4.850000000000001,
424
+ // "chart":[
425
+ // [1612519260000,44099,44099,44099,44099,0,441],
426
+ // [1612519200000,44099,44099,44099,44099,0,440],
427
+ // [1612519140000,44269,44271,44269,44271,0,439],
428
+ // ]
429
+ // }
430
+ //
431
+ const chart = this.safeValue (response, 'chart', []);
432
+ return this.parseOHLCVs (chart, market, timeframe, since, limit);
433
+ }
434
+
435
+ parseOHLCV (ohlcv, market = undefined) {
436
+ //
437
+ // [
438
+ // 1612519260000, // timestamp
439
+ // 44099, // open
440
+ // 44099, // high
441
+ // 44099, // low
442
+ // 44099, // close
443
+ // 0, // base volume
444
+ // 441, // seqNumber
445
+ // ]
446
+ //
447
+ const timestamp = this.safeInteger (ohlcv, 0);
448
+ const open = this.parseNumber (this.convertFromScale (this.safeString (ohlcv, 1), market['precision']['price']));
449
+ const high = this.parseNumber (this.convertFromScale (this.safeString (ohlcv, 2), market['precision']['price']));
450
+ const low = this.parseNumber (this.convertFromScale (this.safeString (ohlcv, 3), market['precision']['price']));
451
+ const close = this.parseNumber (this.convertFromScale (this.safeString (ohlcv, 4), market['precision']['price']));
452
+ const volume = this.parseNumber (this.convertFromScale (this.safeString (ohlcv, 5), market['precision']['amount']));
453
+ return [ timestamp, open, high, low, close, volume ];
454
+ }
455
+
456
+ parseBidAsk (bidask, priceKey = 0, amountKey = 1, market = undefined) {
457
+ if (market === undefined) {
458
+ throw new ArgumentsRequired (this.id + ' parseBidAsk() requires a market argument');
459
+ }
460
+ const priceString = this.safeString (bidask, priceKey);
461
+ const amountString = this.safeString (bidask, amountKey);
462
+ return [
463
+ this.parseNumber (this.convertFromScale (priceString, market['precision']['price'])),
464
+ this.parseNumber (this.convertFromScale (amountString, market['precision']['amount'])),
465
+ ];
466
+ }
467
+
468
+ parseOrderBook (orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 0, amountKey = 1, market = undefined) {
469
+ const result = {
470
+ 'timestamp': timestamp,
471
+ 'datetime': this.iso8601 (timestamp),
472
+ 'nonce': undefined,
473
+ };
474
+ const sides = [ bidsKey, asksKey ];
475
+ for (let i = 0; i < sides.length; i++) {
476
+ const side = sides[i];
477
+ const orders = [];
478
+ const bidasks = this.safeValue (orderbook, side);
479
+ for (let k = 0; k < bidasks.length; k++) {
480
+ orders.push (this.parseBidAsk (bidasks[k], priceKey, amountKey, market));
481
+ }
482
+ result[side] = orders;
483
+ }
484
+ result[bidsKey] = this.sortBy (result[bidsKey], 0, true);
485
+ result[asksKey] = this.sortBy (result[asksKey], 0);
486
+ return result;
487
+ }
488
+
489
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
490
+ await this.loadMarkets ();
491
+ const market = this.market (symbol);
492
+ const request = {
493
+ 'pairId': parseInt (market['id']),
494
+ };
495
+ const response = await this.publicGetGetOrderBook (this.extend (request, params));
496
+ //
497
+ // {
498
+ // "bids":[
499
+ // [4000480,30000,1612644984667],
500
+ // [3999304,200000,1612644984667],
501
+ // [3998862,50000,1612644984667],
502
+ // ],
503
+ // "asks":[
504
+ // [4001962,1790000,1612644984667],
505
+ // [4002616,1000,1612644984667],
506
+ // [4003889,1000,1612644984667],
507
+ // ],
508
+ // "usdMark":40011.02,
509
+ // "marketStatus":0,
510
+ // "estFundingRate":0.0,
511
+ // "fundingRateTime":0,
512
+ // "auctionPrice":0.0,
513
+ // "auctionVolume":0.0
514
+ // }
515
+ //
516
+ return this.parseOrderBook (response, symbol, undefined, 'bids', 'asks', 0, 1, market);
517
+ }
518
+
519
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
520
+ await this.loadMarkets ();
521
+ const market = this.market (symbol);
522
+ const request = {
523
+ 'pairId': parseInt (market['id']),
524
+ };
525
+ const response = await this.publicGetGetTradeHistory (this.extend (request, params));
526
+ //
527
+ // {
528
+ // "trades":[
529
+ // [4022800,47000,"20210206-21:39:12.886",256323,1],
530
+ // [4023066,1000,"20210206-21:38:55.030",256322,1],
531
+ // [4022406,50000,"20210206-21:36:56.334",256321,1],
532
+ // ]
533
+ // }
534
+ //
535
+ const trades = this.safeValue (response, 'trades', []);
536
+ return this.parseTrades (trades, market, since, limit, params);
537
+ }
538
+
539
+ parseTrade (trade, market = undefined) {
540
+ //
541
+ // public fetchTrades
542
+ //
543
+ // [
544
+ // 4022800, // 0 price
545
+ // 47000, // 1 quantity
546
+ // "20210206-21:39:12.886", // 2 timestamp
547
+ // 256323, // 3 sequence number
548
+ // 1 // 4 taker side 1 = buy, 2 = sell
549
+ // ]
550
+ //
551
+ // private fetchMyTrades
552
+ //
553
+ // {
554
+ // "account":3583,
555
+ // "commission":"-0.015805",
556
+ // "commCurrency":"USDC",
557
+ // "execId":265757,
558
+ // "ordType":"2",
559
+ // "ordStatus":"2",
560
+ // "execType":"F",
561
+ // "aggressorIndicator":true,
562
+ // "orderId":388953019,
563
+ // "price":"1842.04",
564
+ // "qty":"0.010000",
565
+ // "lastPx":"1756.22",
566
+ // "avgPx":"1756.22",
567
+ // "cumQty":"0.010000",
568
+ // "quoteQty":"0.010000",
569
+ // "side":"BUY",
570
+ // "symbol":"ETH/USDC",
571
+ // "clOrdId":"1613106766970339107",
572
+ // "submitterId":3583,
573
+ // "targetStrategy":"0",
574
+ // "time":1613106766971,
575
+ // "date":"20210212-05:12:46.971"
576
+ // }
577
+ //
578
+ let id = undefined;
579
+ let timestamp = undefined;
580
+ let orderId = undefined;
581
+ let type = undefined;
582
+ let side = undefined;
583
+ let priceString = undefined;
584
+ let amountString = undefined;
585
+ let fee = undefined;
586
+ let marketId = undefined;
587
+ if (Array.isArray (trade)) {
588
+ id = this.safeString (trade, 3);
589
+ priceString = this.convertFromScale (this.safeString (trade, 0), market['precision']['price']);
590
+ amountString = this.convertFromScale (this.safeString (trade, 1), market['precision']['amount']);
591
+ timestamp = this.toMilliseconds (this.safeString (trade, 2));
592
+ const takerSide = this.safeInteger (trade, 4);
593
+ if (takerSide === 1) {
594
+ side = 'buy';
595
+ } else if (takerSide === 2) {
596
+ side = 'sell';
597
+ }
598
+ } else {
599
+ id = this.safeString (trade, 'execId');
600
+ timestamp = this.safeInteger (trade, 'time');
601
+ marketId = this.safeString (trade, 'symbol');
602
+ orderId = this.safeString (trade, 'orderId');
603
+ side = this.safeStringLower (trade, 'side');
604
+ type = this.parseOrderType (this.safeString (trade, 'ordType'));
605
+ priceString = this.safeString (trade, 'lastPx');
606
+ amountString = this.safeString (trade, 'qty');
607
+ let feeCostString = this.safeString (trade, 'commission');
608
+ if (feeCostString !== undefined) {
609
+ feeCostString = Precise.stringNeg (feeCostString);
610
+ const feeCurrencyId = this.safeString (trade, 'commCurrency');
611
+ const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
612
+ fee = {
613
+ 'cost': feeCostString,
614
+ 'currency': feeCurrencyCode,
615
+ };
616
+ }
617
+ }
618
+ market = this.safeMarket (marketId, market);
619
+ return this.safeTrade ({
620
+ 'info': trade,
621
+ 'id': id,
622
+ 'timestamp': timestamp,
623
+ 'datetime': this.iso8601 (timestamp),
624
+ 'symbol': market['symbol'],
625
+ 'order': orderId,
626
+ 'type': type,
627
+ 'side': side,
628
+ 'takerOrMaker': undefined,
629
+ 'price': priceString,
630
+ 'amount': amountString,
631
+ 'cost': undefined,
632
+ 'fee': fee,
633
+ }, market);
634
+ }
635
+
636
+ parseBalance (response) {
637
+ const positions = this.safeValue (response, 'positions', []);
638
+ const result = {
639
+ 'info': response,
640
+ };
641
+ for (let i = 0; i < positions.length; i++) {
642
+ const position = positions[i];
643
+ const assetType = this.safeString (position, 'assetType');
644
+ if (assetType === 'ASSET') {
645
+ const currencyId = this.safeString (position, 'symbol');
646
+ const code = this.safeCurrencyCode (currencyId);
647
+ const quantityString = this.safeString (position, 'quantity');
648
+ const availableQuantityString = this.safeString (position, 'availableQuantity');
649
+ const scale = this.safeInteger (position, 'quantity_scale');
650
+ const account = this.account ();
651
+ account['free'] = this.convertFromScale (availableQuantityString, scale);
652
+ account['total'] = this.convertFromScale (quantityString, scale);
653
+ result[code] = account;
654
+ }
655
+ }
656
+ return this.safeBalance (result);
657
+ }
658
+
659
+ async fetchBalance (params = {}) {
660
+ await this.loadMarkets ();
661
+ const response = await this.privatePostGetPositions (params);
662
+ // {
663
+ // "positions":[
664
+ // {
665
+ // "instrumentId":1,
666
+ // "userId":3583,
667
+ // "quantity":0,
668
+ // "availableQuantity":0,
669
+ // "quantity_scale":6,
670
+ // "symbol":"USDC",
671
+ // "assetType":"ASSET",
672
+ // "usdCostBasis":0.0,
673
+ // "usdAvgCostBasis":0.0,
674
+ // "usdValue":0.0,
675
+ // "usdUnrealized":0.0,
676
+ // "usdRealized":0.0,
677
+ // "baseUsdMark":1.0,
678
+ // "settleCoinUsdMark":0.0,
679
+ // "settleCoinUnrealized":0.0,
680
+ // "settleCoinRealized":0.0
681
+ // },
682
+ // ]
683
+ // }
684
+ return this.parseBalance (response);
685
+ }
686
+
687
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
688
+ await this.loadMarkets ();
689
+ const market = this.market (symbol);
690
+ const orderSide = (side === 'buy') ? 1 : 2;
691
+ const quantityScale = this.getScale (amount);
692
+ const request = {
693
+ // 'id': 0,
694
+ // 'account': 0, // required for institutional users
695
+ 'instrumentId': parseInt (market['id']),
696
+ 'symbol': market['uppercaseId'],
697
+ // 'clOrdId': '',
698
+ 'side': orderSide, // 1 = buy, 2 = sell
699
+ // 'ordType': 1, // 1 = market, 2 = limit, 3 = stop market, 4 = stop limit
700
+ // 'price': this.priceToPrecision (symbol, price), // required for limit and stop limit orders
701
+ // 'price_scale': this.getScale (price),
702
+ 'quantity': this.convertToScale (this.numberToString (amount), quantityScale),
703
+ 'quantity_scale': quantityScale,
704
+ // 'stopPx': this.priceToPrecision (symbol, stopPx),
705
+ // 'stopPx_scale': this.getScale (stopPx),
706
+ // 'targetStrategy': 0,
707
+ // 'isHidden': false,
708
+ // 'timeInForce': 1, // 1 = Good Till Cancel (GTC), 3 = Immediate or Cancel (IOC), 4 = Fill or Kill (FOK), 5 = Good Till Crossing (GTX), 6 = Good Till Date (GTD)
709
+ // 'interval': 0,
710
+ // 'intervalCount': 0,
711
+ // 'intervalDelay': 0,
712
+ // 'price2': 0,
713
+ // 'price2_scale': this.getScale (price2),
714
+ // 'blockWaitAck': 0, // 1 = wait for order acknowledgement, when set, response will include the matching engine "orderId" field
715
+ };
716
+ if (type === 'market') {
717
+ request['ordType'] = 1;
718
+ } else if (type === 'limit') {
719
+ request['ordType'] = 2;
720
+ const priceScale = this.getScale (price);
721
+ request['price'] = this.convertToScale (this.numberToString (price), priceScale);
722
+ request['priceScale'] = priceScale;
723
+ } else {
724
+ const stopPrice = this.safeNumber2 (params, 'stopPrice', 'stopPx');
725
+ params = this.omit (params, [ 'stopPrice', 'stopPx' ]);
726
+ if (stopPrice === undefined) {
727
+ if (type === 'stop') {
728
+ if (price === undefined) {
729
+ throw new ArgumentsRequired (this.id + ' createOrder() requires a price argument or a stopPrice parameter or a stopPx parameter for ' + type + ' orders');
730
+ }
731
+ request['ordType'] = 3;
732
+ request['stopPx'] = this.convertToScale (this.numberToString (price), this.getScale (price));
733
+ } else if (type === 'stop limit') {
734
+ throw new ArgumentsRequired (this.id + ' createOrder() requires a stopPrice parameter or a stopPx parameter for ' + type + ' orders');
735
+ }
736
+ } else {
737
+ if (type === 'stop') {
738
+ request['ordType'] = 3;
739
+ request['stopPx'] = this.convertToScale (this.numberToString (stopPrice), this.getScale (stopPrice));
740
+ } else if (type === 'stop limit') {
741
+ request['ordType'] = 4;
742
+ const priceScale = this.getScale (price);
743
+ const stopPriceScale = this.getScale (stopPrice);
744
+ request['price_scale'] = priceScale;
745
+ request['stopPx_scale'] = stopPriceScale;
746
+ request['stopPx'] = this.convertToScale (this.numberToString (stopPrice), stopPriceScale);
747
+ request['price'] = this.convertToScale (this.numberToString (price), priceScale);
748
+ }
749
+ }
750
+ }
751
+ const response = await this.privatePostOrder (this.extend (request, params));
752
+ //
753
+ // {
754
+ // "status":"sent",
755
+ // "id":385617863,
756
+ // "instrumentId":53,
757
+ // "clOrdId":"1613037510849637345",
758
+ // "userId":3583,
759
+ // "price":2000,
760
+ // "quantity":200,
761
+ // "ordType":2
762
+ // }
763
+ //
764
+ return this.parseOrder (response, market);
765
+ }
766
+
767
+ async cancelOrder (id, symbol = undefined, params = {}) {
768
+ if (symbol === undefined) {
769
+ throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
770
+ }
771
+ await this.loadMarkets ();
772
+ const market = this.market (symbol);
773
+ const request = {
774
+ 'origOrderId': parseInt (id),
775
+ 'instrumentId': parseInt (market['id']),
776
+ };
777
+ const response = await this.privatePostCancelOrder (this.extend (request, params));
778
+ //
779
+ // {
780
+ // "status":"sent",
781
+ // "id":0,
782
+ // "origOrderId":385613629,
783
+ // "instrumentId":53,
784
+ // "userId":3583,
785
+ // "price":0,
786
+ // "quantity":0,
787
+ // "ordType":0
788
+ // }
789
+ //
790
+ return this.parseOrder (response, market);
791
+ }
792
+
793
+ async editOrder (id, symbol, type, side, amount, price = undefined, params = {}) {
794
+ await this.loadMarkets ();
795
+ const market = this.market (symbol);
796
+ const orderSide = (side === 'buy') ? 1 : 2;
797
+ const quantityScale = this.getScale (amount);
798
+ const request = {
799
+ // 'id': 0,
800
+ 'origOrderId': id,
801
+ // 'account': 0, // required for institutional users
802
+ 'instrumentId': parseInt (market['id']),
803
+ 'symbol': market['uppercaseId'],
804
+ // 'clOrdId': '',
805
+ 'side': orderSide, // 1 = buy, 2 = sell
806
+ // 'ordType': 1, // 1 = market, 2 = limit, 3 = stop market, 4 = stop limit
807
+ // 'price': this.priceToPrecision (symbol, price), // required for limit and stop limit orders
808
+ // 'price_scale': this.getScale (price),
809
+ 'quantity': this.convertToScale (this.numberToString (amount), quantityScale),
810
+ 'quantity_scale': quantityScale,
811
+ // 'stopPx': this.priceToPrecision (symbol, stopPx),
812
+ // 'stopPx_scale': this.getScale (stopPx),
813
+ // 'timeInForce': 1, // 1 = Good Till Cancel (GTC), 3 = Immediate or Cancel (IOC), 4 = Fill or Kill (FOK), 5 = Good Till Crossing (GTX), 6 = Good Till Date (GTD)
814
+ };
815
+ if (type === 'market') {
816
+ request['ordType'] = 1;
817
+ } else if (type === 'limit') {
818
+ request['ordType'] = 2;
819
+ request['price'] = this.convertToScale (this.numberToString (price), this.getScale (price));
820
+ } else {
821
+ const stopPrice = this.safeNumber2 (params, 'stopPrice', 'stopPx');
822
+ params = this.omit (params, [ 'stopPrice', 'stopPx' ]);
823
+ if (stopPrice === undefined) {
824
+ if (type === 'stop') {
825
+ if (price === undefined) {
826
+ throw new ArgumentsRequired (this.id + ' editOrder() requires a price argument or a stopPrice parameter or a stopPx parameter for ' + type + ' orders');
827
+ }
828
+ request['ordType'] = 3;
829
+ request['stopPx'] = this.convertToScale (this.numberToString (price), this.getScale (price));
830
+ } else if (type === 'stop limit') {
831
+ throw new ArgumentsRequired (this.id + ' editOrder() requires a stopPrice parameter or a stopPx parameter for ' + type + ' orders');
832
+ }
833
+ } else {
834
+ if (type === 'stop') {
835
+ request['ordType'] = 3;
836
+ request['stopPx'] = this.convertToScale (this.numberToString (stopPrice), this.getScale (stopPrice));
837
+ } else if (type === 'stop limit') {
838
+ request['ordType'] = 4;
839
+ const priceScale = this.getScale (price);
840
+ const stopPriceScale = this.getScale (stopPrice);
841
+ request['price_scale'] = priceScale;
842
+ request['stopPx_scale'] = stopPriceScale;
843
+ request['stopPx'] = this.convertToScale (this.numberToString (stopPrice), stopPriceScale);
844
+ request['price'] = this.convertToScale (this.numberToString (price), priceScale);
845
+ }
846
+ }
847
+ }
848
+ const response = await this.privatePostOrder (this.extend (request, params));
849
+ //
850
+ // {
851
+ // "status":"sent",
852
+ // "id":385617863,
853
+ // "instrumentId":53,
854
+ // "clOrdId":"1613037510849637345",
855
+ // "userId":3583,
856
+ // "price":2000,
857
+ // "quantity":200,
858
+ // "ordType":2
859
+ // }
860
+ //
861
+ return this.parseOrder (response, market);
862
+ }
863
+
864
+ async fetchOrder (id, symbol = undefined, params = {}) {
865
+ await this.loadMarkets ();
866
+ const request = {
867
+ 'orderId': parseInt (id),
868
+ };
869
+ const response = await this.privatePostGetOrderStatus (this.extend (request, params));
870
+ //
871
+ // {
872
+ // "orderId":388953019,
873
+ // "clOrdId":"1613106766970339107",
874
+ // "symbol":"ETH/USDC",
875
+ // "instrumentId":53,
876
+ // "side":"1",
877
+ // "userId":3583,
878
+ // "account":3583,
879
+ // "execType":"F",
880
+ // "ordType":"2",
881
+ // "ordStatus":"2",
882
+ // "timeInForce":"3",
883
+ // "timeStamp":"20210212-05:12:46.971",
884
+ // "execId":265757,
885
+ // "targetStrategy":0,
886
+ // "isHidden":false,
887
+ // "isReduceOnly":false,
888
+ // "isLiquidation":false,
889
+ // "fee":0,
890
+ // "fee_scale":6,
891
+ // "feeInstrumentId":1,
892
+ // "price":184204,
893
+ // "price_scale":2,
894
+ // "quantity":10000,
895
+ // "quantity_scale":6,
896
+ // "leavesQty":0,
897
+ // "leavesQty_scale":6,
898
+ // "cumQty":10000,
899
+ // "cumQty_scale":6,
900
+ // "lastPx":175622,
901
+ // "lastPx_scale":2,
902
+ // "avgPx":175622,
903
+ // "avgPx_scale":2,
904
+ // "lastQty":10000,
905
+ // "lastQty_scale":6
906
+ // }
907
+ //
908
+ return this.parseOrder (response);
909
+ }
910
+
911
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
912
+ const request = {
913
+ 'ordStatus': '2', // '0' = New, '1' = Partially filled, '2' = Filled, '4' = Cancelled, '8' = Rejected, 'C' = Expired
914
+ };
915
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
916
+ }
917
+
918
+ async fetchCanceledOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
919
+ const request = {
920
+ 'ordStatus': '4', // '0' = New, '1' = Partially filled, '2' = Filled, '4' = Cancelled, '8' = Rejected, 'C' = Expired
921
+ };
922
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
923
+ }
924
+
925
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
926
+ await this.loadMarkets ();
927
+ let market = undefined;
928
+ const request = {
929
+ // 'account': id, // for institutional users
930
+ // 'symbol': marketSymbol, // cannot be used with instrumentId
931
+ // 'instrumentId': market['numericId'],
932
+ // 'limit': limit,
933
+ // 'execType': execType, // '0' = New, '4' = Canceled, '5' = Replace, '8' = Rejected, 'C' = Expired, 'F' = Fill Status, 'I' = Order Status
934
+ // 'ordStatus': ordStatus, // '0' = New, '1' = Partially filled, '2' = Filled, '4' = Cancelled, '8' = Rejected, 'C' = Expired
935
+ };
936
+ if (symbol !== undefined) {
937
+ market = this.market (symbol);
938
+ request['instrumentId'] = parseInt (market['id']);
939
+ }
940
+ if (limit !== undefined) {
941
+ request['limit'] = limit;
942
+ }
943
+ const response = await this.privatePostGetOrders (this.extend (request, params));
944
+ //
945
+ // {
946
+ // "isInitialSnap":false,
947
+ // "orders":[
948
+ // {
949
+ // "orderId":385613629,
950
+ // "orderUpdateSeq":1,
951
+ // "clOrdId":"1613037448945798198",
952
+ // "symbol":"ETH/USDC",
953
+ // "instrumentId":53,
954
+ // "side":"1",
955
+ // "userId":3583,
956
+ // "account":3583,
957
+ // "execType":"4",
958
+ // "ordType":"2",
959
+ // "ordStatus":"C",
960
+ // "timeInForce":"3",
961
+ // "timeStamp":"20210211-09:57:28.944",
962
+ // "execId":0,
963
+ // "targetStrategy":0,
964
+ // "isHidden":false,
965
+ // "isReduceOnly":false,
966
+ // "isLiquidation":false,
967
+ // "fee":0,
968
+ // "feeTotal":0,
969
+ // "fee_scale":0,
970
+ // "feeInstrumentId":0,
971
+ // "price":999,
972
+ // "price_scale":2,
973
+ // "quantity":10000000,
974
+ // "quantity_scale":6,
975
+ // "leavesQty":10000000,
976
+ // "leavesQty_scale":6,
977
+ // "cumQty":0,
978
+ // "cumQty_scale":0,
979
+ // "lastPx":0,
980
+ // "lastPx_scale":2,
981
+ // "avgPx":0,
982
+ // "avgPx_scale":0,
983
+ // "lastQty":0,
984
+ // "lastQty_scale":6
985
+ // }
986
+ // ]
987
+ // }
988
+ //
989
+ const orders = this.safeValue (response, 'orders', []);
990
+ return this.parseOrders (orders, market, since, limit, params);
991
+ }
992
+
993
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
994
+ await this.loadMarkets ();
995
+ const request = {
996
+ // 'account': 123, // for institutional users
997
+ // 'instrumentId': market['id'],
998
+ // 'startTime': since,
999
+ // 'endTime': this.milliseconds (),
1000
+ };
1001
+ let market = undefined;
1002
+ if (symbol !== undefined) {
1003
+ market = this.market (symbol);
1004
+ request['instrumentId'] = market['id'];
1005
+ }
1006
+ if (since !== undefined) {
1007
+ request['startTime'] = since;
1008
+ }
1009
+ const response = await this.privatePostUserTrades (this.extend (request, params));
1010
+ //
1011
+ // {
1012
+ // "trades":[
1013
+ // {
1014
+ // "account":3583,
1015
+ // "commission":"-0.015805",
1016
+ // "commCurrency":"USDC",
1017
+ // "execId":265757,
1018
+ // "ordType":"2",
1019
+ // "ordStatus":"2",
1020
+ // "execType":"F",
1021
+ // "aggressorIndicator":true,
1022
+ // "orderId":388953019,
1023
+ // "price":"1842.04",
1024
+ // "qty":"0.010000",
1025
+ // "lastPx":"1756.22",
1026
+ // "avgPx":"1756.22",
1027
+ // "cumQty":"0.010000",
1028
+ // "quoteQty":"0.010000",
1029
+ // "side":"BUY",
1030
+ // "symbol":"ETH/USDC",
1031
+ // "clOrdId":"1613106766970339107",
1032
+ // "submitterId":3583,
1033
+ // "targetStrategy":"0",
1034
+ // "time":1613106766971,
1035
+ // "date":"20210212-05:12:46.971"
1036
+ // }
1037
+ // ]
1038
+ // }
1039
+ //
1040
+ const trades = this.safeValue (response, 'trades', []);
1041
+ return this.parseTrades (trades, market, since, limit, params);
1042
+ }
1043
+
1044
+ async fetchDepositAddress (code, params = {}) {
1045
+ await this.loadMarkets ();
1046
+ const currency = this.currency (code);
1047
+ const request = {
1048
+ 'instrumentId': parseInt (currency['id']),
1049
+ };
1050
+ const response = await this.privatePostGetDepositAddresses (this.extend (request, params));
1051
+ //
1052
+ // {
1053
+ // "addresses":[
1054
+ // {"instrumentId":1,"userId":3583,"symbol":"USDC","address":"0xdff47af071ea3c537e57278290516cda32a78b97","status":1}
1055
+ // ]
1056
+ // }
1057
+ //
1058
+ const addresses = this.safeValue (response, 'addresses', []);
1059
+ const address = this.safeValue (addresses, 0);
1060
+ return this.parseDepositAddress (address, currency);
1061
+ }
1062
+
1063
+ parseDepositAddress (depositAddress, currency = undefined) {
1064
+ //
1065
+ // {
1066
+ // "instrumentId":1,
1067
+ // "userId":3583,
1068
+ // "symbol":"USDC",
1069
+ // "address":"0xdff47af071ea3c537e57278290516cda32a78b97",
1070
+ // "status":1
1071
+ // }
1072
+ //
1073
+ const currencyId = this.safeString (depositAddress, 'symbol');
1074
+ const code = this.safeCurrencyCode (currencyId, currency);
1075
+ const address = this.safeString (depositAddress, 'address');
1076
+ this.checkAddress (address);
1077
+ return {
1078
+ 'currency': code,
1079
+ 'address': address,
1080
+ 'tag': undefined,
1081
+ 'network': undefined,
1082
+ 'info': depositAddress,
1083
+ };
1084
+ }
1085
+
1086
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1087
+ await this.loadMarkets ();
1088
+ const request = {};
1089
+ let currency = undefined;
1090
+ if (code !== undefined) {
1091
+ currency = this.currency (code);
1092
+ request['instrumentId'] = parseInt (currency['id']);
1093
+ }
1094
+ const response = await this.privatePostGetDepositHistory (this.extend (request, params));
1095
+ //
1096
+ // {
1097
+ // "deposits":[
1098
+ // {
1099
+ // "id":4309,
1100
+ // "instrumentId":1,
1101
+ // "userId":3583,
1102
+ // "symbol":"USDC",
1103
+ // "address":"null",
1104
+ // "timestamp":"1613021112189",
1105
+ // "status":1,
1106
+ // "balance":0.0,
1107
+ // "balance_change":100.0,
1108
+ // "confirms":1,
1109
+ // "transactionId":"caba4500-489f-424e-abd7-b4dabc09a800"
1110
+ // }
1111
+ // ]
1112
+ // }
1113
+ //
1114
+ const deposits = this.safeValue (response, 'deposits', []);
1115
+ return this.parseTransactions (deposits, currency, since, limit, { 'type': 'deposit' });
1116
+ }
1117
+
1118
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1119
+ await this.loadMarkets ();
1120
+ const request = {};
1121
+ let currency = undefined;
1122
+ if (code !== undefined) {
1123
+ currency = this.currency (code);
1124
+ request['instrumentId'] = parseInt (currency['id']);
1125
+ }
1126
+ const response = await this.privatePostGetWithdrawRequests (this.extend (request, params));
1127
+ //
1128
+ // {
1129
+ // "addresses":[
1130
+ // {
1131
+ // "id":3841,
1132
+ // "instrumentId":3,
1133
+ // "userId":4245,
1134
+ // "symbol":"BTC",
1135
+ // "address":"XXXXXYYYYYZZZZZ",
1136
+ // "timestamp":"20200806-11:04:35.053",
1137
+ // "status":0,
1138
+ // "balance":1,
1139
+ // "balance_scale":3,
1140
+ // "confirms":0,
1141
+ // "transactionId":"null"
1142
+ // }
1143
+ // ]
1144
+ // }
1145
+ //
1146
+ const withdrawals = this.safeValue (response, 'addresses', []);
1147
+ return this.parseTransactions (withdrawals, currency, since, limit, { 'type': 'withdrawal' });
1148
+ }
1149
+
1150
+ parseTransaction (transaction, currency = undefined) {
1151
+ //
1152
+ // fetchDeposits, fetchWithdrawals
1153
+ //
1154
+ // {
1155
+ // "id":4309,
1156
+ // "instrumentId":1,
1157
+ // "userId":3583,
1158
+ // "symbol":"USDC",
1159
+ // "address":"null",
1160
+ // "timestamp":"1613021112189",
1161
+ // "status":1,
1162
+ // "balance":0.0,
1163
+ // "balance_change":100.0,
1164
+ // "confirms":1,
1165
+ // "transactionId":"caba4500-489f-424e-abd7-b4dabc09a800"
1166
+ // }
1167
+ //
1168
+ // withdraw
1169
+ //
1170
+ // {
1171
+ // "instrumentId": 1,
1172
+ // "userId": 23750,
1173
+ // "symbol": "USDC",
1174
+ // "timestamp": "20200201-05:37:16.584",
1175
+ // "status": 1,
1176
+ // "userUuid": "b9e33713-c28f-468f-99bd-f6deab0dd854",
1177
+ // "currencyCode": "USDC",
1178
+ // "address": "2MvW97yT6E2Kq8bWc1aj1DqfbgMzjRNk2LE",
1179
+ // "quantity": 20,
1180
+ // "requestUuid": "56782b34-8a78-4f5f-b164-4b8f7d583b7f",
1181
+ // "transactionUuid": "1004eb0f-41e1-41e9-9d48-8eefcc6c09f2",
1182
+ // "transactionId": "WS23436",
1183
+ // "destinationWalletAlias": "Test",
1184
+ // "quantity_scale": 0
1185
+ // }
1186
+ //
1187
+ const id = this.safeString (transaction, 'id', 'transactionId');
1188
+ const txid = this.safeString (transaction, 'transactionUuid');
1189
+ const timestamp = this.safeInteger (transaction, 'timestamp');
1190
+ let address = this.safeString (transaction, 'address');
1191
+ if (address === 'null') {
1192
+ address = undefined;
1193
+ }
1194
+ const type = this.safeString (transaction, 'type');
1195
+ let amount = this.safeNumber (transaction, 'balance_change');
1196
+ if (amount === undefined) {
1197
+ amount = this.safeString (transaction, 'quantity');
1198
+ const amountScale = this.safeInteger (transaction, 'quantity_scale');
1199
+ amount = this.parseNumber (this.convertFromScale (amount, amountScale));
1200
+ }
1201
+ const currencyId = this.safeString (transaction, 'symbol');
1202
+ const code = this.safeCurrencyCode (currencyId, currency);
1203
+ const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
1204
+ return {
1205
+ 'info': transaction,
1206
+ 'id': id,
1207
+ 'txid': txid,
1208
+ 'timestamp': timestamp,
1209
+ 'datetime': this.iso8601 (timestamp),
1210
+ 'network': undefined,
1211
+ 'addressFrom': undefined,
1212
+ 'address': address,
1213
+ 'addressTo': undefined,
1214
+ 'tagFrom': undefined,
1215
+ 'tag': undefined,
1216
+ 'tagTo': undefined,
1217
+ 'type': type,
1218
+ 'amount': amount,
1219
+ 'currency': code,
1220
+ 'status': status,
1221
+ 'updated': undefined,
1222
+ 'comment': undefined,
1223
+ 'fee': undefined,
1224
+ };
1225
+ }
1226
+
1227
+ parseTransactionStatus (status) {
1228
+ const statuses = {
1229
+ '0': 'pending',
1230
+ '1': 'ok',
1231
+ };
1232
+ return this.safeString (statuses, status, status);
1233
+ }
1234
+
1235
+ async withdraw (code, amount, address, tag = undefined, params = {}) {
1236
+ [ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
1237
+ this.checkAddress (address);
1238
+ await this.loadMarkets ();
1239
+ const currency = this.currency (code);
1240
+ const scale = this.getScale (amount);
1241
+ const quantity = this.convertToScale (amount, scale);
1242
+ const request = {
1243
+ 'instrumentId': parseInt (currency['id']),
1244
+ 'symbol': currency['uppercaseId'],
1245
+ 'quantity': quantity,
1246
+ 'quantity_scale': scale,
1247
+ 'address': address,
1248
+ };
1249
+ const response = await this.privatePostSendWithdrawRequest (this.extend (request, params));
1250
+ //
1251
+ // {
1252
+ // "instrumentId": 1,
1253
+ // "userId": 23750,
1254
+ // "symbol": "USDC",
1255
+ // "timestamp": "20200201-05:37:16.584",
1256
+ // "status": 1,
1257
+ // "userUuid": "b9e33713-c28f-468f-99bd-f6deab0dd854",
1258
+ // "currencyCode": "USDC",
1259
+ // "address": "2MvW97yT6E2Kq8bWc1aj1DqfbgMzjRNk2LE",
1260
+ // "quantity": 20,
1261
+ // "requestUuid": "56782b34-8a78-4f5f-b164-4b8f7d583b7f",
1262
+ // "transactionUuid": "1004eb0f-41e1-41e9-9d48-8eefcc6c09f2",
1263
+ // "transactionId": "WS23436",
1264
+ // "destinationWalletAlias": "Test",
1265
+ // "quantity_scale": 0
1266
+ // }
1267
+ //
1268
+ return this.parseTransaction (response, currency);
1269
+ }
1270
+
1271
+ async fetchTradingFees (params = {}) {
1272
+ await this.loadMarkets ();
1273
+ const response = await this.publicGetGetExchangeInfo (params);
1274
+ //
1275
+ // {
1276
+ // tradingLimits: [],
1277
+ // withdrawLimits: [{ All: '0.0', Type: 'percent' }],
1278
+ // futuresFees: [
1279
+ // { tier: '0', maker: '0.000300', taker: '0.000500' },
1280
+ // { tier: '1', maker: '0.000200', taker: '0.000400' },
1281
+ // { tier: '2', maker: '0.000180', taker: '0.000400' },
1282
+ // ],
1283
+ // spotFees: [
1284
+ // { tier: '0', maker: '0.000900', taker: '0.001500', volume: '0' },
1285
+ // { tier: '1', maker: '0.000600', taker: '0.001250', volume: '200000' },
1286
+ // { tier: '2', maker: '0.000540', taker: '0.001200', volume: '2500000' },
1287
+ // ],
1288
+ // referrals: { earning: '0.30', discount: '0.05', duration: '180' }
1289
+ // }
1290
+ //
1291
+ const spotFees = this.safeValue (response, 'spotFees', []);
1292
+ const firstSpotFee = this.safeValue (spotFees, 0, {});
1293
+ const spotMakerFee = this.safeNumber (firstSpotFee, 'maker');
1294
+ const spotTakerFee = this.safeNumber (firstSpotFee, 'taker');
1295
+ const futureFees = this.safeValue (response, 'futuresFees', []);
1296
+ const firstFutureFee = this.safeValue (futureFees, 0, {});
1297
+ const futureMakerFee = this.safeNumber (firstFutureFee, 'maker');
1298
+ const futureTakerFee = this.safeNumber (firstFutureFee, 'taker');
1299
+ const spotTakerTiers = [];
1300
+ const spotMakerTiers = [];
1301
+ const result = {};
1302
+ for (let i = 0; i < spotFees.length; i++) {
1303
+ const spotFee = spotFees[i];
1304
+ const volume = this.safeNumber (spotFee, 'volume');
1305
+ spotTakerTiers.push ([ volume, this.safeNumber (spotFee, 'taker') ]);
1306
+ spotMakerTiers.push ([ volume, this.safeNumber (spotFee, 'maker') ]);
1307
+ }
1308
+ const spotTiers = {
1309
+ 'taker': spotTakerTiers,
1310
+ 'maker': spotMakerTiers,
1311
+ };
1312
+ const futureTakerTiers = [];
1313
+ const futureMakerTiers = [];
1314
+ for (let i = 0; i < futureFees.length; i++) {
1315
+ const futureFee = futureFees[i];
1316
+ futureTakerTiers.push ([ undefined, this.safeNumber (futureFee, 'taker') ]);
1317
+ futureMakerTiers.push ([ undefined, this.safeNumber (futureFee, 'maker') ]);
1318
+ }
1319
+ const futureTiers = {
1320
+ 'taker': futureTakerTiers,
1321
+ 'maker': futureMakerTiers,
1322
+ };
1323
+ for (let i = 0; i < this.symbols.length; i++) {
1324
+ const symbol = this.symbols[i];
1325
+ const market = this.market (symbol);
1326
+ const fee = {
1327
+ 'info': response,
1328
+ 'symbol': symbol,
1329
+ 'percentage': true,
1330
+ 'tierBased': true,
1331
+ };
1332
+ if (this.safeValue (market, 'spot')) {
1333
+ fee['maker'] = spotMakerFee;
1334
+ fee['taker'] = spotTakerFee;
1335
+ fee['tiers'] = spotTiers;
1336
+ } else if (this.safeValue (market, 'contract')) {
1337
+ fee['maker'] = futureMakerFee;
1338
+ fee['taker'] = futureTakerFee;
1339
+ fee['tiers'] = futureTiers;
1340
+ }
1341
+ result[symbol] = fee;
1342
+ }
1343
+ return result;
1344
+ }
1345
+
1346
+ async fetchTradingLimits (symbols = undefined, params = {}) {
1347
+ await this.loadMarkets ();
1348
+ // getExchangeInfo
1349
+ const response = await this.publicGetGetExchangeInfo (params);
1350
+ const tradingLimits = this.safeValue (response, 'tradingLimits', []);
1351
+ // To-do parsing response when available
1352
+ return {
1353
+ 'info': tradingLimits,
1354
+ 'limits': {
1355
+ 'amount': {
1356
+ 'min': undefined,
1357
+ 'max': undefined,
1358
+ },
1359
+ 'price': {
1360
+ 'min': undefined,
1361
+ 'max': undefined,
1362
+ },
1363
+ 'cost': {
1364
+ 'min': undefined,
1365
+ 'max': undefined,
1366
+ },
1367
+ },
1368
+ };
1369
+ }
1370
+
1371
+ async fetchFundingLimits (params = {}) {
1372
+ // getExchangeInfo
1373
+ const response = await this.publicGetGetExchangeInfo (params);
1374
+ const withdrawLimits = this.safeValue (response, 'withdrawLimits', []);
1375
+ // TO-DO parse response when available
1376
+ return {
1377
+ 'info': withdrawLimits,
1378
+ 'withdraw': undefined,
1379
+ };
1380
+ }
1381
+
1382
+ parseOrder (order, market = undefined) {
1383
+ //
1384
+ // createOrder, editOrder, cancelOrder
1385
+ //
1386
+ // {
1387
+ // "status":"sent",
1388
+ // "id":385617863,
1389
+ // "instrumentId":53,
1390
+ // "clOrdId":"1613037510849637345",
1391
+ // "userId":3583,
1392
+ // "price":2000,
1393
+ // "quantity":200,
1394
+ // "ordType":2
1395
+ // }
1396
+ //
1397
+ // fetchOrders, fetchOrder
1398
+ //
1399
+ // {
1400
+ // "orderId":385613629,
1401
+ // "orderUpdateSeq":1,
1402
+ // "clOrdId":"1613037448945798198",
1403
+ // "symbol":"ETH/USDC",
1404
+ // "instrumentId":53,
1405
+ // "side":"1",
1406
+ // "userId":3583,
1407
+ // "account":3583,
1408
+ // "execType":"4",
1409
+ // "ordType":"2",
1410
+ // "ordStatus":"C",
1411
+ // "timeInForce":"3",
1412
+ // "timeStamp":"20210211-09:57:28.944",
1413
+ // "execId":0,
1414
+ // "targetStrategy":0,
1415
+ // "isHidden":false,
1416
+ // "isReduceOnly":false,
1417
+ // "isLiquidation":false,
1418
+ // "fee":0,
1419
+ // "feeTotal":0,
1420
+ // "fee_scale":0,
1421
+ // "feeInstrumentId":0,
1422
+ // "price":999,
1423
+ // "price_scale":2,
1424
+ // "quantity":10000000,
1425
+ // "quantity_scale":6,
1426
+ // "leavesQty":10000000,
1427
+ // "leavesQty_scale":6,
1428
+ // "cumQty":0,
1429
+ // "cumQty_scale":0,
1430
+ // "lastPx":0,
1431
+ // "lastPx_scale":2,
1432
+ // "avgPx":0,
1433
+ // "avgPx_scale":0,
1434
+ // "lastQty":0,
1435
+ // "lastQty_scale":6
1436
+ // }
1437
+ //
1438
+ let id = this.safeString2 (order, 'orderId', 'id');
1439
+ id = this.safeString (order, 'origOrderId', id);
1440
+ const clientOrderId = this.safeString (order, 'clOrdId');
1441
+ const type = this.parseOrderType (this.safeString (order, 'ordType'));
1442
+ const side = this.parseOrderSide (this.safeString (order, 'side'));
1443
+ const status = this.parseOrderStatus (this.safeString (order, 'ordStatus'));
1444
+ const marketId = this.safeString (order, 'instrumentId');
1445
+ const symbol = this.safeSymbol (marketId, market);
1446
+ const timestamp = this.toMilliseconds (this.safeString (order, 'timeStamp'));
1447
+ const lastTradeTimestamp = undefined;
1448
+ let priceString = this.safeString (order, 'price');
1449
+ const priceScale = this.safeInteger (order, 'price_scale');
1450
+ priceString = this.convertFromScale (priceString, priceScale);
1451
+ let amountString = this.safeString (order, 'quantity');
1452
+ const amountScale = this.safeInteger (order, 'quantity_scale');
1453
+ amountString = this.convertFromScale (amountString, amountScale);
1454
+ let filledString = this.safeString (order, 'cumQty');
1455
+ const filledScale = this.safeInteger (order, 'cumQty_scale');
1456
+ filledString = this.convertFromScale (filledString, filledScale);
1457
+ let remainingString = this.safeString (order, 'leavesQty');
1458
+ const remainingScale = this.safeInteger (order, 'leavesQty_scale');
1459
+ remainingString = this.convertFromScale (remainingString, remainingScale);
1460
+ let fee = undefined;
1461
+ const currencyId = this.safeInteger (order, 'feeInstrumentId');
1462
+ const feeCurrencyCode = this.safeCurrencyCode (currencyId);
1463
+ let feeCostString = undefined;
1464
+ let feeCost = this.safeString (order, 'feeTotal');
1465
+ const feeScale = this.safeInteger (order, 'fee_scale');
1466
+ if (feeCost !== undefined) {
1467
+ feeCost = Precise.stringNeg (feeCost);
1468
+ feeCostString = this.convertFromScale (feeCost, feeScale);
1469
+ }
1470
+ if (feeCost !== undefined) {
1471
+ fee = {
1472
+ 'currency': feeCurrencyCode,
1473
+ 'cost': feeCostString,
1474
+ 'rate': undefined,
1475
+ };
1476
+ }
1477
+ let timeInForce = this.parseTimeInForce (this.safeString (order, 'timeInForce'));
1478
+ if (timeInForce === '0') {
1479
+ timeInForce = undefined;
1480
+ }
1481
+ const stopPriceScale = this.safeInteger (order, 'stopPx_scale', 0);
1482
+ const stopPrice = this.parseNumber (this.convertFromScale (this.safeString (order, 'stopPx'), stopPriceScale));
1483
+ return this.safeOrder ({
1484
+ 'info': order,
1485
+ 'id': id,
1486
+ 'clientOrderId': clientOrderId,
1487
+ 'timestamp': timestamp,
1488
+ 'datetime': this.iso8601 (timestamp),
1489
+ 'lastTradeTimestamp': lastTradeTimestamp,
1490
+ 'symbol': symbol,
1491
+ 'type': type,
1492
+ 'timeInForce': timeInForce,
1493
+ 'postOnly': undefined,
1494
+ 'side': side,
1495
+ 'price': priceString,
1496
+ 'stopPrice': stopPrice,
1497
+ 'amount': amountString,
1498
+ 'cost': undefined,
1499
+ 'average': undefined,
1500
+ 'filled': filledString,
1501
+ 'remaining': remainingString,
1502
+ 'status': status,
1503
+ 'fee': fee,
1504
+ 'trades': undefined,
1505
+ }, market);
1506
+ }
1507
+
1508
+ parseOrderStatus (status) {
1509
+ const statuses = {
1510
+ '0': 'open',
1511
+ '1': 'open', // 'partially filled',
1512
+ '2': 'closed', // 'filled',
1513
+ '3': 'open', // 'done for day',
1514
+ '4': 'canceled',
1515
+ '5': 'canceled', // 'replaced',
1516
+ '6': 'canceling', // 'pending cancel',
1517
+ '7': 'canceled', // 'stopped',
1518
+ '8': 'rejected', // 'rejected',
1519
+ '9': 'canceled', // 'suspended',
1520
+ 'A': 'open', // 'pending new',
1521
+ 'B': 'open', // 'calculated',
1522
+ 'C': 'expired',
1523
+ 'D': 'open', // 'accepted for bidding',
1524
+ 'E': 'canceling', // 'pending replace',
1525
+ 'F': 'open', // 'partial fill or fill',
1526
+ };
1527
+ return this.safeString (statuses, status, status);
1528
+ }
1529
+
1530
+ parseOrderSide (side) {
1531
+ const sides = {
1532
+ '1': 'buy',
1533
+ '2': 'sell',
1534
+ };
1535
+ return this.safeString (sides, side, side);
1536
+ }
1537
+
1538
+ parseOrderType (type) {
1539
+ const types = {
1540
+ '1': 'market',
1541
+ '2': 'limit',
1542
+ '3': 'stop',
1543
+ '4': 'stop limit',
1544
+ };
1545
+ return this.safeString (types, type, type);
1546
+ }
1547
+
1548
+ parseTimeInForce (timeInForce) {
1549
+ const timeInForces = {
1550
+ '1': 'GTC', // Good Till Canceled
1551
+ '3': 'IOC', // Immediate or Cancel
1552
+ '4': 'FOK', // Fill or Kill
1553
+ '5': 'GTX', // Good Till Crossing (GTX)
1554
+ '6': 'GTD', // Good Till Date
1555
+ };
1556
+ return this.safeString (timeInForces, timeInForce, timeInForce);
1557
+ }
1558
+
1559
+ toMilliseconds (dateString) {
1560
+ if (dateString === undefined) {
1561
+ return dateString;
1562
+ }
1563
+ // '20200328-10:31:01.575' -> '2020-03-28 12:42:48.000'
1564
+ const splits = dateString.split ('-');
1565
+ const partOne = this.safeString (splits, 0);
1566
+ const partTwo = this.safeString (splits, 1);
1567
+ if (partOne === undefined || partTwo === undefined) {
1568
+ return undefined;
1569
+ }
1570
+ if (partOne.length !== 8) {
1571
+ return undefined;
1572
+ }
1573
+ const date = partOne.slice (0, 4) + '-' + partOne.slice (4, 6) + '-' + partOne.slice (6, 8);
1574
+ return this.parse8601 (date + ' ' + partTwo);
1575
+ }
1576
+
1577
+ convertFromScale (number, scale) {
1578
+ if ((number === undefined) || (scale === undefined)) {
1579
+ return undefined;
1580
+ }
1581
+ const precise = new Precise (number);
1582
+ precise.decimals = precise.decimals + scale;
1583
+ precise.reduce ();
1584
+ return precise.toString ();
1585
+ }
1586
+
1587
+ getScale (num) {
1588
+ const s = this.numberToString (num);
1589
+ return this.precisionFromString (s);
1590
+ }
1591
+
1592
+ convertToScale (number, scale) {
1593
+ if ((number === undefined) || (scale === undefined)) {
1594
+ return undefined;
1595
+ }
1596
+ const precise = new Precise (number);
1597
+ precise.decimals = precise.decimals - scale;
1598
+ precise.reduce ();
1599
+ const preciseString = precise.toString ();
1600
+ return parseInt (preciseString);
1601
+ }
1602
+
1603
+ nonce () {
1604
+ return this.milliseconds ();
1605
+ }
1606
+
1607
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1608
+ if (response === undefined) {
1609
+ return; // fallback to default error handler
1610
+ }
1611
+ const error = this.safeString (response, 'error');
1612
+ if (error !== undefined) {
1613
+ const feedback = this.id + ' ' + body;
1614
+ this.throwExactlyMatchedException (this.exceptions, error, feedback);
1615
+ this.throwBroadlyMatchedException (this.exceptions, body, feedback);
1616
+ throw new ExchangeError (this.id + ' ' + body);
1617
+ }
1618
+ }
1619
+
1620
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1621
+ let url = this.implodeParams (path, params);
1622
+ let query = this.omit (params, this.extractParams (path));
1623
+ if (api === 'public') {
1624
+ if (Object.keys (query).length) {
1625
+ url += '?' + this.urlencode (query);
1626
+ }
1627
+ } else if (api === 'private') {
1628
+ // special case for getUserHistory
1629
+ const format = this.safeValue (params, 'format');
1630
+ const type = this.safeValue (params, 'type');
1631
+ const extension = {};
1632
+ if (format !== undefined) {
1633
+ extension['format'] = format;
1634
+ }
1635
+ if (type !== undefined) {
1636
+ extension['type'] = type;
1637
+ }
1638
+ if (Object.keys (extension).length) {
1639
+ url += '?' + this.urlencode (extension);
1640
+ }
1641
+ params = this.omit (params, [ 'format', 'type' ]);
1642
+ this.checkRequiredCredentials ();
1643
+ const nonce = this.nonce ();
1644
+ query = this.extend (query, {
1645
+ 'userId': this.uid,
1646
+ 'nonce': nonce,
1647
+ });
1648
+ params['nonce'] = this.nonce ();
1649
+ body = this.json (query);
1650
+ const signature = this.hmac (this.encode (body), this.encode (this.secret), 'sha384');
1651
+ headers = {
1652
+ 'Content-Type': 'application/json',
1653
+ 'requestToken': this.apiKey,
1654
+ 'signature': signature,
1655
+ };
1656
+ }
1657
+ url = this.urls['api'][api] + '/' + url;
1658
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1659
+ }
1660
+ };