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/oceanex.js ADDED
@@ -0,0 +1,816 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, AuthenticationError, ArgumentsRequired, BadRequest, InvalidOrder, InsufficientFunds, OrderNotFound, PermissionDenied } = require ('./base/errors');
7
+
8
+ // ---------------------------------------------------------------------------
9
+
10
+ module.exports = class oceanex extends Exchange {
11
+ describe () {
12
+ return this.deepExtend (super.describe (), {
13
+ 'id': 'oceanex',
14
+ 'name': 'OceanEx',
15
+ 'countries': [ 'BS' ], // Bahamas
16
+ 'version': 'v1',
17
+ 'rateLimit': 3000,
18
+ 'urls': {
19
+ 'logo': 'https://user-images.githubusercontent.com/1294454/58385970-794e2d80-8001-11e9-889c-0567cd79b78e.jpg',
20
+ 'api': 'https://api.oceanex.pro',
21
+ 'www': 'https://www.oceanex.pro.com',
22
+ 'doc': 'https://api.oceanex.pro/doc/v1',
23
+ 'referral': 'https://oceanex.pro/signup?referral=VE24QX',
24
+ },
25
+ 'has': {
26
+ 'CORS': undefined,
27
+ 'spot': true,
28
+ 'margin': false,
29
+ 'swap': undefined, // has but unimplemented
30
+ 'future': undefined,
31
+ 'option': undefined,
32
+ 'cancelAllOrders': true,
33
+ 'cancelOrder': true,
34
+ 'cancelOrders': true,
35
+ 'createMarketOrder': true,
36
+ 'createOrder': true,
37
+ 'fetchBalance': true,
38
+ 'fetchBorrowRate': false,
39
+ 'fetchBorrowRateHistories': false,
40
+ 'fetchBorrowRateHistory': false,
41
+ 'fetchBorrowRates': false,
42
+ 'fetchBorrowRatesPerSymbol': false,
43
+ 'fetchClosedOrders': true,
44
+ 'fetchFundingFees': undefined,
45
+ 'fetchMarkets': true,
46
+ 'fetchOHLCV': true,
47
+ 'fetchOpenOrders': true,
48
+ 'fetchOrder': true,
49
+ 'fetchOrderBook': true,
50
+ 'fetchOrderBooks': true,
51
+ 'fetchOrders': true,
52
+ 'fetchTicker': true,
53
+ 'fetchTickers': true,
54
+ 'fetchTime': true,
55
+ 'fetchTrades': true,
56
+ 'fetchTradingFee': false,
57
+ 'fetchTradingFees': true,
58
+ 'fetchTradingLimits': undefined,
59
+ },
60
+ 'timeframes': {
61
+ '1m': '1',
62
+ '5m': '5',
63
+ '15m': '15',
64
+ '30m': '30',
65
+ '1h': '60',
66
+ '2h': '120',
67
+ '4h': '240',
68
+ '6h': '360',
69
+ '12h': '720',
70
+ '1d': '1440',
71
+ '3d': '4320',
72
+ '1w': '10080',
73
+ },
74
+ 'api': {
75
+ 'public': {
76
+ 'get': [
77
+ 'markets',
78
+ 'tickers/{pair}',
79
+ 'tickers_multi',
80
+ 'order_book',
81
+ 'order_book/multi',
82
+ 'fees/trading',
83
+ 'trades',
84
+ 'timestamp',
85
+ ],
86
+ 'post': [
87
+ 'k',
88
+ ],
89
+ },
90
+ 'private': {
91
+ 'get': [
92
+ 'key',
93
+ 'members/me',
94
+ 'orders',
95
+ 'orders/filter',
96
+ ],
97
+ 'post': [
98
+ 'orders',
99
+ 'orders/multi',
100
+ 'order/delete',
101
+ 'order/delete/multi',
102
+ 'orders/clear',
103
+ ],
104
+ },
105
+ },
106
+ 'fees': {
107
+ 'trading': {
108
+ 'tierBased': false,
109
+ 'percentage': true,
110
+ 'maker': this.parseNumber ('0.001'),
111
+ 'taker': this.parseNumber ('0.001'),
112
+ },
113
+ },
114
+ 'commonCurrencies': {
115
+ 'PLA': 'Plair',
116
+ },
117
+ 'exceptions': {
118
+ 'codes': {
119
+ '-1': BadRequest,
120
+ '-2': BadRequest,
121
+ '1001': BadRequest,
122
+ '1004': ArgumentsRequired,
123
+ '1006': AuthenticationError,
124
+ '1008': AuthenticationError,
125
+ '1010': AuthenticationError,
126
+ '1011': PermissionDenied,
127
+ '2001': AuthenticationError,
128
+ '2002': InvalidOrder,
129
+ '2004': OrderNotFound,
130
+ '9003': PermissionDenied,
131
+ },
132
+ 'exact': {
133
+ 'market does not have a valid value': BadRequest,
134
+ 'side does not have a valid value': BadRequest,
135
+ 'Account::AccountError: Cannot lock funds': InsufficientFunds,
136
+ 'The account does not exist': AuthenticationError,
137
+ },
138
+ },
139
+ });
140
+ }
141
+
142
+ async fetchMarkets (params = {}) {
143
+ const request = { 'show_details': true };
144
+ const response = await this.publicGetMarkets (this.extend (request, params));
145
+ //
146
+ // {
147
+ // id: 'xtzusdt',
148
+ // name: 'XTZ/USDT',
149
+ // ask_precision: '8',
150
+ // bid_precision: '8',
151
+ // enabled: true,
152
+ // price_precision: '4',
153
+ // amount_precision: '3',
154
+ // usd_precision: '4',
155
+ // minimum_trading_amount: '1.0'
156
+ // },
157
+ //
158
+ const result = [];
159
+ const markets = this.safeValue (response, 'data');
160
+ for (let i = 0; i < markets.length; i++) {
161
+ const market = markets[i];
162
+ const id = this.safeValue (market, 'id');
163
+ const name = this.safeValue (market, 'name');
164
+ let [ baseId, quoteId ] = name.split ('/');
165
+ const base = this.safeCurrencyCode (baseId);
166
+ const quote = this.safeCurrencyCode (quoteId);
167
+ baseId = baseId.toLowerCase ();
168
+ quoteId = quoteId.toLowerCase ();
169
+ const symbol = base + '/' + quote;
170
+ result.push ({
171
+ 'id': id,
172
+ 'symbol': symbol,
173
+ 'base': base,
174
+ 'quote': quote,
175
+ 'settle': undefined,
176
+ 'baseId': baseId,
177
+ 'quoteId': quoteId,
178
+ 'settleId': undefined,
179
+ 'type': 'spot',
180
+ 'spot': true,
181
+ 'margin': false,
182
+ 'swap': false,
183
+ 'future': false,
184
+ 'option': false,
185
+ 'active': undefined,
186
+ 'contract': false,
187
+ 'linear': undefined,
188
+ 'inverse': undefined,
189
+ 'contractSize': undefined,
190
+ 'expiry': undefined,
191
+ 'expiryDatetime': undefined,
192
+ 'strike': undefined,
193
+ 'optionType': undefined,
194
+ 'precision': {
195
+ 'amount': this.safeInteger (market, 'amount_precision'),
196
+ 'price': this.safeInteger (market, 'price_precision'),
197
+ 'base': this.safeInteger (market, 'ask_precision'),
198
+ 'quote': this.safeInteger (market, 'bid_precision'),
199
+ },
200
+ 'limits': {
201
+ 'leverage': {
202
+ 'min': undefined,
203
+ 'max': undefined,
204
+ },
205
+ 'amount': {
206
+ 'min': undefined,
207
+ 'max': undefined,
208
+ },
209
+ 'price': {
210
+ 'min': undefined,
211
+ 'max': undefined,
212
+ },
213
+ 'cost': {
214
+ 'min': this.safeNumber (market, 'minimum_trading_amount'),
215
+ 'max': undefined,
216
+ },
217
+ },
218
+ 'info': market,
219
+ });
220
+ }
221
+ return result;
222
+ }
223
+
224
+ async fetchTicker (symbol, params = {}) {
225
+ await this.loadMarkets ();
226
+ const market = this.market (symbol);
227
+ const request = {
228
+ 'pair': market['id'],
229
+ };
230
+ const response = await this.publicGetTickersPair (this.extend (request, params));
231
+ //
232
+ // {
233
+ // "code":0,
234
+ // "message":"Operation successful",
235
+ // "data": {
236
+ // "at":1559431729,
237
+ // "ticker": {
238
+ // "buy":"0.0065",
239
+ // "sell":"0.00677",
240
+ // "low":"0.00677",
241
+ // "high":"0.00677",
242
+ // "last":"0.00677",
243
+ // "vol":"2000.0"
244
+ // }
245
+ // }
246
+ // }
247
+ //
248
+ const data = this.safeValue (response, 'data', {});
249
+ return this.parseTicker (data, market);
250
+ }
251
+
252
+ async fetchTickers (symbols = undefined, params = {}) {
253
+ await this.loadMarkets ();
254
+ if (symbols === undefined) {
255
+ symbols = this.symbols;
256
+ }
257
+ const marketIds = this.marketIds (symbols);
258
+ const request = { 'markets': marketIds };
259
+ const response = await this.publicGetTickersMulti (this.extend (request, params));
260
+ //
261
+ // {
262
+ // "code":0,
263
+ // "message":"Operation successful",
264
+ // "data": {
265
+ // "at":1559431729,
266
+ // "ticker": {
267
+ // "buy":"0.0065",
268
+ // "sell":"0.00677",
269
+ // "low":"0.00677",
270
+ // "high":"0.00677",
271
+ // "last":"0.00677",
272
+ // "vol":"2000.0"
273
+ // }
274
+ // }
275
+ // }
276
+ //
277
+ const data = this.safeValue (response, 'data');
278
+ const result = {};
279
+ for (let i = 0; i < data.length; i++) {
280
+ const ticker = data[i];
281
+ const marketId = this.safeString (ticker, 'market');
282
+ const market = this.safeMarket (marketId);
283
+ const symbol = market['symbol'];
284
+ result[symbol] = this.parseTicker (ticker, market);
285
+ }
286
+ return this.filterByArray (result, 'symbol', symbols);
287
+ }
288
+
289
+ parseTicker (data, market = undefined) {
290
+ //
291
+ // {
292
+ // "at":1559431729,
293
+ // "ticker": {
294
+ // "buy":"0.0065",
295
+ // "sell":"0.00677",
296
+ // "low":"0.00677",
297
+ // "high":"0.00677",
298
+ // "last":"0.00677",
299
+ // "vol":"2000.0"
300
+ // }
301
+ // }
302
+ //
303
+ const ticker = this.safeValue (data, 'ticker', {});
304
+ const timestamp = this.safeTimestamp (data, 'at');
305
+ const symbol = this.safeSymbol (undefined, market);
306
+ return this.safeTicker ({
307
+ 'symbol': symbol,
308
+ 'timestamp': timestamp,
309
+ 'datetime': this.iso8601 (timestamp),
310
+ 'high': this.safeString (ticker, 'high'),
311
+ 'low': this.safeString (ticker, 'low'),
312
+ 'bid': this.safeString (ticker, 'buy'),
313
+ 'bidVolume': undefined,
314
+ 'ask': this.safeString (ticker, 'sell'),
315
+ 'askVolume': undefined,
316
+ 'vwap': undefined,
317
+ 'open': undefined,
318
+ 'close': this.safeString (ticker, 'last'),
319
+ 'last': this.safeString (ticker, 'last'),
320
+ 'previousClose': undefined,
321
+ 'change': undefined,
322
+ 'percentage': undefined,
323
+ 'average': undefined,
324
+ 'baseVolume': this.safeString (ticker, 'volume'),
325
+ 'quoteVolume': undefined,
326
+ 'info': ticker,
327
+ }, market, false);
328
+ }
329
+
330
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
331
+ await this.loadMarkets ();
332
+ const market = this.market (symbol);
333
+ const request = {
334
+ 'market': market['id'],
335
+ };
336
+ if (limit !== undefined) {
337
+ request['limit'] = limit;
338
+ }
339
+ const response = await this.publicGetOrderBook (this.extend (request, params));
340
+ //
341
+ // {
342
+ // "code":0,
343
+ // "message":"Operation successful",
344
+ // "data": {
345
+ // "timestamp":1559433057,
346
+ // "asks": [
347
+ // ["100.0","20.0"],
348
+ // ["4.74","2000.0"],
349
+ // ["1.74","4000.0"],
350
+ // ],
351
+ // "bids":[
352
+ // ["0.0065","5482873.4"],
353
+ // ["0.00649","4781956.2"],
354
+ // ["0.00648","2876006.8"],
355
+ // ],
356
+ // }
357
+ // }
358
+ //
359
+ const orderbook = this.safeValue (response, 'data', {});
360
+ const timestamp = this.safeTimestamp (orderbook, 'timestamp');
361
+ return this.parseOrderBook (orderbook, symbol, timestamp);
362
+ }
363
+
364
+ async fetchOrderBooks (symbols = undefined, limit = undefined, params = {}) {
365
+ await this.loadMarkets ();
366
+ if (symbols === undefined) {
367
+ symbols = this.symbols;
368
+ }
369
+ const marketIds = this.marketIds (symbols);
370
+ const request = {
371
+ 'markets': marketIds,
372
+ };
373
+ if (limit !== undefined) {
374
+ request['limit'] = limit;
375
+ }
376
+ const response = await this.publicGetOrderBookMulti (this.extend (request, params));
377
+ //
378
+ // {
379
+ // "code":0,
380
+ // "message":"Operation successful",
381
+ // "data": [
382
+ // {
383
+ // "timestamp":1559433057,
384
+ // "market": "bagvet",
385
+ // "asks": [
386
+ // ["100.0","20.0"],
387
+ // ["4.74","2000.0"],
388
+ // ["1.74","4000.0"],
389
+ // ],
390
+ // "bids":[
391
+ // ["0.0065","5482873.4"],
392
+ // ["0.00649","4781956.2"],
393
+ // ["0.00648","2876006.8"],
394
+ // ],
395
+ // },
396
+ // ...,
397
+ // ],
398
+ // }
399
+ //
400
+ const data = this.safeValue (response, 'data', []);
401
+ const result = {};
402
+ for (let i = 0; i < data.length; i++) {
403
+ const orderbook = data[i];
404
+ const marketId = this.safeString (orderbook, 'market');
405
+ const symbol = this.safeSymbol (marketId);
406
+ const timestamp = this.safeTimestamp (orderbook, 'timestamp');
407
+ result[symbol] = this.parseOrderBook (orderbook, symbol, timestamp);
408
+ }
409
+ return result;
410
+ }
411
+
412
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
413
+ await this.loadMarkets ();
414
+ const market = this.market (symbol);
415
+ const request = {
416
+ 'market': market['id'],
417
+ };
418
+ if (limit !== undefined) {
419
+ request['limit'] = limit;
420
+ }
421
+ const response = await this.publicGetTrades (this.extend (request, params));
422
+ //
423
+ // {
424
+ // "code":0,
425
+ // "message":"Operation successful",
426
+ // "data": [
427
+ // {
428
+ // "id":220247666,
429
+ // "price":"3098.62",
430
+ // "volume":"0.00196",
431
+ // "funds":"6.0732952",
432
+ // "market":"ethusdt",
433
+ // "created_at":"2022-04-19T19:03:15Z",
434
+ // "created_on":1650394995,
435
+ // "side":"bid"
436
+ // },
437
+ // ]
438
+ // }
439
+ //
440
+ const data = this.safeValue (response, 'data');
441
+ return this.parseTrades (data, market, since, limit);
442
+ }
443
+
444
+ parseTrade (trade, market = undefined) {
445
+ //
446
+ // fetchTrades (public)
447
+ //
448
+ // {
449
+ // "id":220247666,
450
+ // "price":"3098.62",
451
+ // "volume":"0.00196",
452
+ // "funds":"6.0732952",
453
+ // "market":"ethusdt",
454
+ // "created_at":"2022-04-19T19:03:15Z",
455
+ // "created_on":1650394995,
456
+ // "side":"bid"
457
+ // }
458
+ //
459
+ let side = this.safeValue (trade, 'side');
460
+ if (side === 'bid') {
461
+ side = 'buy';
462
+ } else if (side === 'ask') {
463
+ side = 'sell';
464
+ }
465
+ const marketId = this.safeValue (trade, 'market');
466
+ const symbol = this.safeSymbol (marketId, market);
467
+ let timestamp = this.safeTimestamp (trade, 'created_on');
468
+ if (timestamp === undefined) {
469
+ timestamp = this.parse8601 (this.safeString (trade, 'created_at'));
470
+ }
471
+ const priceString = this.safeString (trade, 'price');
472
+ const amountString = this.safeString (trade, 'volume');
473
+ return this.safeTrade ({
474
+ 'info': trade,
475
+ 'timestamp': timestamp,
476
+ 'datetime': this.iso8601 (timestamp),
477
+ 'symbol': symbol,
478
+ 'id': this.safeString (trade, 'id'),
479
+ 'order': undefined,
480
+ 'type': 'limit',
481
+ 'takerOrMaker': undefined,
482
+ 'side': side,
483
+ 'price': priceString,
484
+ 'amount': amountString,
485
+ 'cost': undefined,
486
+ 'fee': undefined,
487
+ }, market);
488
+ }
489
+
490
+ async fetchTime (params = {}) {
491
+ const response = await this.publicGetTimestamp (params);
492
+ //
493
+ // {"code":0,"message":"Operation successful","data":1559433420}
494
+ //
495
+ return this.safeTimestamp (response, 'data');
496
+ }
497
+
498
+ async fetchTradingFees (params = {}) {
499
+ const response = await this.publicGetFeesTrading (params);
500
+ const data = this.safeValue (response, 'data');
501
+ const result = {};
502
+ for (let i = 0; i < data.length; i++) {
503
+ const group = data[i];
504
+ const maker = this.safeValue (group, 'ask_fee', {});
505
+ const taker = this.safeValue (group, 'bid_fee', {});
506
+ const marketId = this.safeString (group, 'market');
507
+ const symbol = this.safeSymbol (marketId);
508
+ result[symbol] = {
509
+ 'info': group,
510
+ 'symbol': symbol,
511
+ 'maker': this.safeNumber (maker, 'value'),
512
+ 'taker': this.safeNumber (taker, 'value'),
513
+ 'percentage': true,
514
+ };
515
+ }
516
+ return result;
517
+ }
518
+
519
+ async fetchKey (params = {}) {
520
+ const response = await this.privateGetKey (params);
521
+ return this.safeValue (response, 'data');
522
+ }
523
+
524
+ parseBalance (response) {
525
+ const data = this.safeValue (response, 'data');
526
+ const balances = this.safeValue (data, 'accounts');
527
+ const result = { 'info': response };
528
+ for (let i = 0; i < balances.length; i++) {
529
+ const balance = balances[i];
530
+ const currencyId = this.safeValue (balance, 'currency');
531
+ const code = this.safeCurrencyCode (currencyId);
532
+ const account = this.account ();
533
+ account['free'] = this.safeString (balance, 'balance');
534
+ account['used'] = this.safeString (balance, 'locked');
535
+ result[code] = account;
536
+ }
537
+ return this.safeBalance (result);
538
+ }
539
+
540
+ async fetchBalance (params = {}) {
541
+ await this.loadMarkets ();
542
+ const response = await this.privateGetMembersMe (params);
543
+ return this.parseBalance (response);
544
+ }
545
+
546
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
547
+ await this.loadMarkets ();
548
+ const market = this.market (symbol);
549
+ const request = {
550
+ 'market': market['id'],
551
+ 'side': side,
552
+ 'ord_type': type,
553
+ 'volume': this.amountToPrecision (symbol, amount),
554
+ };
555
+ if (type === 'limit') {
556
+ request['price'] = this.priceToPrecision (symbol, price);
557
+ }
558
+ const response = await this.privatePostOrders (this.extend (request, params));
559
+ const data = this.safeValue (response, 'data');
560
+ return this.parseOrder (data, market);
561
+ }
562
+
563
+ async fetchOrder (id, symbol = undefined, params = {}) {
564
+ let ids = id;
565
+ if (!Array.isArray (id)) {
566
+ ids = [ id ];
567
+ }
568
+ await this.loadMarkets ();
569
+ let market = undefined;
570
+ if (symbol !== undefined) {
571
+ market = this.market (symbol);
572
+ }
573
+ const request = { 'ids': ids };
574
+ const response = await this.privateGetOrders (this.extend (request, params));
575
+ const data = this.safeValue (response, 'data');
576
+ const dataLength = data.length;
577
+ if (data === undefined) {
578
+ throw new OrderNotFound (this.id + ' could not found matching order');
579
+ }
580
+ if (Array.isArray (id)) {
581
+ return this.parseOrders (data, market);
582
+ }
583
+ if (dataLength === 0) {
584
+ throw new OrderNotFound (this.id + ' could not found matching order');
585
+ }
586
+ return this.parseOrder (data[0], market);
587
+ }
588
+
589
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
590
+ const request = {
591
+ 'states': [ 'wait' ],
592
+ };
593
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
594
+ }
595
+
596
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
597
+ const request = {
598
+ 'states': [ 'done', 'cancel' ],
599
+ };
600
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
601
+ }
602
+
603
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
604
+ if (symbol === undefined) {
605
+ throw new ArgumentsRequired (this.id + ' fetchOrders() requires a `symbol` argument');
606
+ }
607
+ await this.loadMarkets ();
608
+ const market = this.market (symbol);
609
+ const states = this.safeValue (params, 'states', [ 'wait', 'done', 'cancel' ]);
610
+ const query = this.omit (params, 'states');
611
+ const request = {
612
+ 'market': market['id'],
613
+ 'states': states,
614
+ 'need_price': 'True',
615
+ };
616
+ if (limit !== undefined) {
617
+ request['limit'] = limit;
618
+ }
619
+ const response = await this.privateGetOrdersFilter (this.extend (request, query));
620
+ const data = this.safeValue (response, 'data', []);
621
+ let result = [];
622
+ for (let i = 0; i < data.length; i++) {
623
+ const orders = this.safeValue (data[i], 'orders', []);
624
+ const status = this.parseOrderStatus (this.safeValue (data[i], 'state'));
625
+ const parsedOrders = this.parseOrders (orders, market, since, limit, { 'status': status });
626
+ result = this.arrayConcat (result, parsedOrders);
627
+ }
628
+ return result;
629
+ }
630
+
631
+ parseOHLCV (ohlcv, market = undefined) {
632
+ // [
633
+ // 1559232000,
634
+ // 8889.22,
635
+ // 9028.52,
636
+ // 8889.22,
637
+ // 9028.52
638
+ // 0.3121
639
+ // ]
640
+ return [
641
+ this.safeTimestamp (ohlcv, 0),
642
+ this.safeNumber (ohlcv, 1),
643
+ this.safeNumber (ohlcv, 2),
644
+ this.safeNumber (ohlcv, 3),
645
+ this.safeNumber (ohlcv, 4),
646
+ this.safeNumber (ohlcv, 5),
647
+ ];
648
+ }
649
+
650
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
651
+ await this.loadMarkets ();
652
+ const market = this.market (symbol);
653
+ const request = {
654
+ 'market': market['id'],
655
+ 'period': this.timeframes[timeframe],
656
+ };
657
+ if (since !== undefined) {
658
+ request['timestamp'] = since;
659
+ }
660
+ if (limit !== undefined) {
661
+ request['limit'] = limit;
662
+ }
663
+ const response = await this.publicPostK (this.extend (request, params));
664
+ const ohlcvs = this.safeValue (response, 'data', []);
665
+ return this.parseOHLCVs (ohlcvs, market, timeframe, since, limit);
666
+ }
667
+
668
+ parseOrder (order, market = undefined) {
669
+ //
670
+ // {
671
+ // "created_at": "2019-01-18T00:38:18Z",
672
+ // "trades_count": 0,
673
+ // "remaining_volume": "0.2",
674
+ // "price": "1001.0",
675
+ // "created_on": "1547771898",
676
+ // "side": "buy",
677
+ // "volume": "0.2",
678
+ // "state": "wait",
679
+ // "ord_type": "limit",
680
+ // "avg_price": "0.0",
681
+ // "executed_volume": "0.0",
682
+ // "id": 473797,
683
+ // "market": "veteth"
684
+ // }
685
+ //
686
+ const status = this.parseOrderStatus (this.safeValue (order, 'state'));
687
+ const marketId = this.safeString2 (order, 'market', 'market_id');
688
+ const symbol = this.safeSymbol (marketId, market);
689
+ let timestamp = this.safeTimestamp (order, 'created_on');
690
+ if (timestamp === undefined) {
691
+ timestamp = this.parse8601 (this.safeString (order, 'created_at'));
692
+ }
693
+ const price = this.safeString (order, 'price');
694
+ const average = this.safeString (order, 'avg_price');
695
+ const amount = this.safeString (order, 'volume');
696
+ const remaining = this.safeString (order, 'remaining_volume');
697
+ const filled = this.safeString (order, 'executed_volume');
698
+ return this.safeOrder ({
699
+ 'info': order,
700
+ 'id': this.safeString (order, 'id'),
701
+ 'clientOrderId': undefined,
702
+ 'timestamp': timestamp,
703
+ 'datetime': this.iso8601 (timestamp),
704
+ 'lastTradeTimestamp': undefined,
705
+ 'symbol': symbol,
706
+ 'type': this.safeValue (order, 'ord_type'),
707
+ 'timeInForce': undefined,
708
+ 'postOnly': undefined,
709
+ 'side': this.safeValue (order, 'side'),
710
+ 'price': price,
711
+ 'stopPrice': undefined,
712
+ 'average': average,
713
+ 'amount': amount,
714
+ 'remaining': remaining,
715
+ 'filled': filled,
716
+ 'status': status,
717
+ 'cost': undefined,
718
+ 'trades': undefined,
719
+ 'fee': undefined,
720
+ }, market);
721
+ }
722
+
723
+ parseOrderStatus (status) {
724
+ const statuses = {
725
+ 'wait': 'open',
726
+ 'done': 'closed',
727
+ 'cancel': 'canceled',
728
+ };
729
+ return this.safeString (statuses, status, status);
730
+ }
731
+
732
+ async createOrders (symbol, orders, params = {}) {
733
+ await this.loadMarkets ();
734
+ const market = this.market (symbol);
735
+ const request = {
736
+ 'market': market['id'],
737
+ 'orders': orders,
738
+ };
739
+ // orders: [{"side":"buy", "volume":.2, "price":1001}, {"side":"sell", "volume":0.2, "price":1002}]
740
+ const response = await this.privatePostOrdersMulti (this.extend (request, params));
741
+ const data = response['data'];
742
+ return this.parseOrders (data);
743
+ }
744
+
745
+ async cancelOrder (id, symbol = undefined, params = {}) {
746
+ await this.loadMarkets ();
747
+ const response = await this.privatePostOrderDelete (this.extend ({ 'id': id }, params));
748
+ const data = this.safeValue (response, 'data');
749
+ return this.parseOrder (data);
750
+ }
751
+
752
+ async cancelOrders (ids, symbol = undefined, params = {}) {
753
+ await this.loadMarkets ();
754
+ const response = await this.privatePostOrderDeleteMulti (this.extend ({ 'ids': ids }, params));
755
+ const data = this.safeValue (response, 'data');
756
+ return this.parseOrders (data);
757
+ }
758
+
759
+ async cancelAllOrders (symbol = undefined, params = {}) {
760
+ await this.loadMarkets ();
761
+ const response = await this.privatePostOrdersClear (params);
762
+ const data = this.safeValue (response, 'data');
763
+ return this.parseOrders (data);
764
+ }
765
+
766
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
767
+ let url = this.urls['api'] + '/' + this.version + '/' + this.implodeParams (path, params);
768
+ const query = this.omit (params, this.extractParams (path));
769
+ if (api === 'public') {
770
+ if (path === 'tickers_multi' || path === 'order_book/multi') {
771
+ let request = '?';
772
+ const markets = this.safeValue (params, 'markets');
773
+ for (let i = 0; i < markets.length; i++) {
774
+ request += 'markets[]=' + markets[i] + '&';
775
+ }
776
+ const limit = this.safeValue (params, 'limit');
777
+ if (limit !== undefined) {
778
+ request += 'limit=' + limit;
779
+ }
780
+ url += request;
781
+ } else if (Object.keys (query).length) {
782
+ url += '?' + this.urlencode (query);
783
+ }
784
+ } else if (api === 'private') {
785
+ this.checkRequiredCredentials ();
786
+ const request = {
787
+ 'uid': this.apiKey,
788
+ 'data': query,
789
+ };
790
+ // to set the private key:
791
+ // const fs = require ('fs')
792
+ // exchange.secret = fs.readFileSync ('oceanex.pem', 'utf8')
793
+ const jwt_token = this.jwt (request, this.encode (this.secret), 'RS256');
794
+ url += '?user_jwt=' + jwt_token;
795
+ }
796
+ headers = { 'Content-Type': 'application/json' };
797
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
798
+ }
799
+
800
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
801
+ //
802
+ // {"code":1011,"message":"This IP 'x.x.x.x' is not allowed","data":{}}
803
+ //
804
+ if (response === undefined) {
805
+ return;
806
+ }
807
+ const errorCode = this.safeString (response, 'code');
808
+ const message = this.safeString (response, 'message');
809
+ if ((errorCode !== undefined) && (errorCode !== '0')) {
810
+ const feedback = this.id + ' ' + body;
811
+ this.throwExactlyMatchedException (this.exceptions['codes'], errorCode, feedback);
812
+ this.throwExactlyMatchedException (this.exceptions['exact'], message, feedback);
813
+ throw new ExchangeError (feedback);
814
+ }
815
+ }
816
+ };