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.
- package/.cache/eslintcache +1 -0
- package/.dockerignore +6 -0
- package/.eslintignore +1 -0
- package/.gitattributes +5 -0
- package/.readthedocs.yaml +16 -0
- package/CONTRIBUTING.md +1049 -0
- package/LICENSE.txt +21 -0
- package/README.md +537 -0
- package/SECURITY.md +5 -0
- package/build/cleanup-old-tags.js +94 -0
- package/build/countries.js +256 -0
- package/build/export-exchanges.js +520 -0
- package/build/fs.js +51 -0
- package/build/transpile.js +1772 -0
- package/build/vss.js +78 -0
- package/ccxt.browser.js +7 -0
- package/ccxt.d.ts +692 -0
- package/ccxt.js +171 -0
- package/cleanup.sh +2 -0
- package/composer-install.sh +20 -0
- package/dist/ccxt.browser.js +208383 -0
- package/gource.sh +3 -0
- package/index.html +7 -0
- package/js/.eslintrc +87 -0
- package/js/aax.js +2686 -0
- package/js/ascendex.js +2584 -0
- package/js/base/.eslintrc.js +43 -0
- package/js/base/Exchange.js +2371 -0
- package/js/base/Precise.js +283 -0
- package/js/base/errorHierarchy.js +47 -0
- package/js/base/errors.js +55 -0
- package/js/base/functions/crypto.js +158 -0
- package/js/base/functions/encode.js +118 -0
- package/js/base/functions/generic.js +270 -0
- package/js/base/functions/misc.js +138 -0
- package/js/base/functions/number.js +329 -0
- package/js/base/functions/platform.js +38 -0
- package/js/base/functions/string.js +21 -0
- package/js/base/functions/throttle.js +79 -0
- package/js/base/functions/time.js +210 -0
- package/js/base/functions/type.js +66 -0
- package/js/base/functions.js +28 -0
- package/js/bequant.js +32 -0
- package/js/bibox.js +1407 -0
- package/js/bigone.js +1366 -0
- package/js/binance.js +5652 -0
- package/js/binancecoinm.js +46 -0
- package/js/binanceus.js +46 -0
- package/js/binanceusdm.js +49 -0
- package/js/bit2c.js +535 -0
- package/js/bitbank.js +842 -0
- package/js/bitbay.js +16 -0
- package/js/bitbns.js +1073 -0
- package/js/bitcoincom.js +15 -0
- package/js/bitfinex.js +1433 -0
- package/js/bitfinex2.js +2025 -0
- package/js/bitflyer.js +840 -0
- package/js/bitforex.js +614 -0
- package/js/bitget.js +2397 -0
- package/js/bithumb.js +980 -0
- package/js/bitmart.js +2516 -0
- package/js/bitmex.js +1809 -0
- package/js/bitopro.js +1443 -0
- package/js/bitpanda.js +1782 -0
- package/js/bitrue.js +1747 -0
- package/js/bitso.js +1062 -0
- package/js/bitstamp.js +1757 -0
- package/js/bitstamp1.js +343 -0
- package/js/bittrex.js +1876 -0
- package/js/bitvavo.js +1579 -0
- package/js/bkex.js +1233 -0
- package/js/bl3p.js +346 -0
- package/js/blockchaincom.js +969 -0
- package/js/btcalpha.js +680 -0
- package/js/btcbox.js +477 -0
- package/js/btcmarkets.js +1022 -0
- package/js/btctradeua.js +466 -0
- package/js/btcturk.js +734 -0
- package/js/buda.js +946 -0
- package/js/bw.js +1265 -0
- package/js/bybit.js +3372 -0
- package/js/bytetrade.js +1336 -0
- package/js/cdax.js +1646 -0
- package/js/cex.js +1410 -0
- package/js/coinbase.js +1342 -0
- package/js/coinbaseprime.js +31 -0
- package/js/coinbasepro.js +1466 -0
- package/js/coincheck.js +755 -0
- package/js/coinex.js +3400 -0
- package/js/coinfalcon.js +880 -0
- package/js/coinmate.js +794 -0
- package/js/coinone.js +816 -0
- package/js/coinspot.js +345 -0
- package/js/crex24.js +1636 -0
- package/js/cryptocom.js +1832 -0
- package/js/currencycom.js +1748 -0
- package/js/delta.js +1547 -0
- package/js/deribit.js +2148 -0
- package/js/digifinex.js +1585 -0
- package/js/eqonex.js +1660 -0
- package/js/exmo.js +1670 -0
- package/js/fairdesk.js +1231 -0
- package/js/flowbtc.js +35 -0
- package/js/fmfwio.js +34 -0
- package/js/ftx.js +2751 -0
- package/js/ftxus.js +38 -0
- package/js/gateio.js +4174 -0
- package/js/gemini.js +1397 -0
- package/js/hitbtc.js +1343 -0
- package/js/hitbtc3.js +2329 -0
- package/js/hollaex.js +1486 -0
- package/js/huobi.js +5706 -0
- package/js/huobijp.js +1710 -0
- package/js/huobipro.js +18 -0
- package/js/idex.js +1439 -0
- package/js/independentreserve.js +649 -0
- package/js/indodax.js +742 -0
- package/js/itbit.js +722 -0
- package/js/kraken.js +2179 -0
- package/js/kucoin.js +2571 -0
- package/js/kucoinfutures.js +1771 -0
- package/js/kuna.js +809 -0
- package/js/latoken.js +1445 -0
- package/js/lbank.js +760 -0
- package/js/liquid.js +1432 -0
- package/js/luno.js +873 -0
- package/js/lykke.js +1147 -0
- package/js/mercado.js +771 -0
- package/js/mexc.js +3151 -0
- package/js/ndax.js +2233 -0
- package/js/novadax.js +1318 -0
- package/js/oceanex.js +816 -0
- package/js/okcoin.js +3841 -0
- package/js/okex.js +16 -0
- package/js/okex5.js +16 -0
- package/js/okx.js +4795 -0
- package/js/paymium.js +498 -0
- package/js/phemex.js +2957 -0
- package/js/poloniex.js +1674 -0
- package/js/probit.js +1346 -0
- package/js/qtrade.js +1588 -0
- package/js/ripio.js +1061 -0
- package/js/static_dependencies/BN/bn.js +3526 -0
- package/js/static_dependencies/README.md +1 -0
- package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
- package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
- package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
- package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
- package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
- package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
- package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
- package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
- package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
- package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
- package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
- package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
- package/js/static_dependencies/node-fetch/index.js +1564 -0
- package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
- package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
- package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
- package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
- package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
- package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
- package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
- package/js/static_dependencies/node-rsa/formats/components.js +71 -0
- package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
- package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
- package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
- package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
- package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
- package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
- package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
- package/js/static_dependencies/node-rsa/utils.js +98 -0
- package/js/static_dependencies/qs/formats.js +18 -0
- package/js/static_dependencies/qs/index.js +11 -0
- package/js/static_dependencies/qs/parse.js +242 -0
- package/js/static_dependencies/qs/stringify.js +269 -0
- package/js/static_dependencies/qs/utils.js +230 -0
- package/js/stex.js +1925 -0
- package/js/test/.eslintrc.js +42 -0
- package/js/test/Exchange/test.balance.js +61 -0
- package/js/test/Exchange/test.borrowRate.js +32 -0
- package/js/test/Exchange/test.currency.js +52 -0
- package/js/test/Exchange/test.fetchBalance.js +23 -0
- package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
- package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
- package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
- package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
- package/js/test/Exchange/test.fetchCurrencies.js +35 -0
- package/js/test/Exchange/test.fetchDeposits.js +31 -0
- package/js/test/Exchange/test.fetchFundingFees.js +19 -0
- package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
- package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
- package/js/test/Exchange/test.fetchLedger.js +42 -0
- package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
- package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
- package/js/test/Exchange/test.fetchMarkets.js +33 -0
- package/js/test/Exchange/test.fetchMyTrades.js +42 -0
- package/js/test/Exchange/test.fetchOHLCV.js +46 -0
- package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
- package/js/test/Exchange/test.fetchOrderBook.js +25 -0
- package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
- package/js/test/Exchange/test.fetchOrders.js +41 -0
- package/js/test/Exchange/test.fetchPositions.js +47 -0
- package/js/test/Exchange/test.fetchStatus.js +35 -0
- package/js/test/Exchange/test.fetchTicker.js +38 -0
- package/js/test/Exchange/test.fetchTickers.js +49 -0
- package/js/test/Exchange/test.fetchTrades.js +39 -0
- package/js/test/Exchange/test.fetchTradingFee.js +18 -0
- package/js/test/Exchange/test.fetchTradingFees.js +22 -0
- package/js/test/Exchange/test.fetchTransactions.js +31 -0
- package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
- package/js/test/Exchange/test.ledgerItem.js +46 -0
- package/js/test/Exchange/test.leverageTier.js +33 -0
- package/js/test/Exchange/test.loadMarkets.js +35 -0
- package/js/test/Exchange/test.market.js +129 -0
- package/js/test/Exchange/test.ohlcv.js +33 -0
- package/js/test/Exchange/test.order.js +62 -0
- package/js/test/Exchange/test.orderbook.js +61 -0
- package/js/test/Exchange/test.position.js +21 -0
- package/js/test/Exchange/test.throttle.js +94 -0
- package/js/test/Exchange/test.ticker.js +95 -0
- package/js/test/Exchange/test.trade.js +68 -0
- package/js/test/Exchange/test.tradingFee.js +34 -0
- package/js/test/Exchange/test.transaction.js +35 -0
- package/js/test/base/.eslintrc +38 -0
- package/js/test/base/functions/test.crypto.js +110 -0
- package/js/test/base/functions/test.datetime.js +62 -0
- package/js/test/base/functions/test.generic.js +152 -0
- package/js/test/base/functions/test.number.js +362 -0
- package/js/test/base/functions/test.time.js +56 -0
- package/js/test/base/functions/test.type.js +53 -0
- package/js/test/base/test.base.js +193 -0
- package/js/test/errors/test.InsufficientFunds.js +86 -0
- package/js/test/errors/test.InvalidNonce.js +64 -0
- package/js/test/errors/test.InvalidOrder.js +35 -0
- package/js/test/errors/test.OrderNotFound.js +39 -0
- package/js/test/test.js +426 -0
- package/js/test/test.timeout_hang.js +12 -0
- package/js/therock.js +1431 -0
- package/js/tidebit.js +632 -0
- package/js/tidex.js +939 -0
- package/js/timex.js +1283 -0
- package/js/upbit.js +1622 -0
- package/js/vcc.js +1353 -0
- package/js/wavesexchange.js +2185 -0
- package/js/wazirx.js +732 -0
- package/js/whitebit.js +1352 -0
- package/js/woo.js +1577 -0
- package/js/xena.js +1948 -0
- package/js/yobit.js +1129 -0
- package/js/zaif.js +647 -0
- package/js/zb.js +4088 -0
- package/js/zipmex.js +40 -0
- package/js/zonda.js +1497 -0
- package/multilang.sh +159 -0
- package/package.json +591 -0
- package/postinstall.js +103 -0
package/js/ascendex.js
ADDED
@@ -0,0 +1,2584 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const { ArgumentsRequired, AuthenticationError, ExchangeError, InsufficientFunds, InvalidOrder, BadSymbol, PermissionDenied, BadRequest } = require ('./base/errors');
|
7
|
+
const { TICK_SIZE } = require ('./base/functions/number');
|
8
|
+
const Precise = require ('./base/Precise');
|
9
|
+
|
10
|
+
// ---------------------------------------------------------------------------
|
11
|
+
|
12
|
+
module.exports = class ascendex extends Exchange {
|
13
|
+
describe () {
|
14
|
+
return this.deepExtend (super.describe (), {
|
15
|
+
'id': 'ascendex',
|
16
|
+
'name': 'AscendEX',
|
17
|
+
'countries': [ 'SG' ], // Singapore
|
18
|
+
// 8 requests per minute = 0.13333 per second => rateLimit = 750
|
19
|
+
// testing 400 works
|
20
|
+
'rateLimit': 400,
|
21
|
+
'certified': true,
|
22
|
+
'pro': true,
|
23
|
+
// new metainfo interface
|
24
|
+
'has': {
|
25
|
+
'CORS': undefined,
|
26
|
+
'spot': true,
|
27
|
+
'margin': true,
|
28
|
+
'swap': true,
|
29
|
+
'future': true,
|
30
|
+
'option': false,
|
31
|
+
'addMargin': true,
|
32
|
+
'cancelAllOrders': true,
|
33
|
+
'cancelOrder': true,
|
34
|
+
'createOrder': true,
|
35
|
+
'createReduceOnlyOrder': true,
|
36
|
+
'createStopLimitOrder': true,
|
37
|
+
'createStopMarketOrder': true,
|
38
|
+
'createStopOrder': true,
|
39
|
+
'fetchAccounts': true,
|
40
|
+
'fetchBalance': true,
|
41
|
+
'fetchClosedOrders': true,
|
42
|
+
'fetchCurrencies': true,
|
43
|
+
'fetchDepositAddress': true,
|
44
|
+
'fetchDepositAddresses': false,
|
45
|
+
'fetchDepositAddressesByNetwork': false,
|
46
|
+
'fetchDeposits': true,
|
47
|
+
'fetchFundingFee': false,
|
48
|
+
'fetchFundingFees': false,
|
49
|
+
'fetchFundingHistory': false,
|
50
|
+
'fetchFundingRate': false,
|
51
|
+
'fetchFundingRateHistory': false,
|
52
|
+
'fetchFundingRates': true,
|
53
|
+
'fetchIndexOHLCV': false,
|
54
|
+
'fetchLeverage': false,
|
55
|
+
'fetchLeverageTiers': true,
|
56
|
+
'fetchMarketLeverageTiers': 'emulated',
|
57
|
+
'fetchMarkets': true,
|
58
|
+
'fetchMarkOHLCV': false,
|
59
|
+
'fetchOHLCV': true,
|
60
|
+
'fetchOpenOrders': true,
|
61
|
+
'fetchOrder': true,
|
62
|
+
'fetchOrderBook': true,
|
63
|
+
'fetchOrders': false,
|
64
|
+
'fetchPosition': false,
|
65
|
+
'fetchPositions': true,
|
66
|
+
'fetchPositionsRisk': false,
|
67
|
+
'fetchPremiumIndexOHLCV': false,
|
68
|
+
'fetchTicker': true,
|
69
|
+
'fetchTickers': true,
|
70
|
+
'fetchTrades': true,
|
71
|
+
'fetchTradingFee': false,
|
72
|
+
'fetchTradingFees': true,
|
73
|
+
'fetchTransactions': true,
|
74
|
+
'fetchTransfer': false,
|
75
|
+
'fetchTransfers': false,
|
76
|
+
'fetchWithdrawal': false,
|
77
|
+
'fetchWithdrawals': true,
|
78
|
+
'reduceMargin': true,
|
79
|
+
'setLeverage': true,
|
80
|
+
'setMarginMode': true,
|
81
|
+
'setPositionMode': false,
|
82
|
+
'transfer': true,
|
83
|
+
},
|
84
|
+
'timeframes': {
|
85
|
+
'1m': '1',
|
86
|
+
'5m': '5',
|
87
|
+
'15m': '15',
|
88
|
+
'30m': '30',
|
89
|
+
'1h': '60',
|
90
|
+
'2h': '120',
|
91
|
+
'4h': '240',
|
92
|
+
'6h': '360',
|
93
|
+
'12h': '720',
|
94
|
+
'1d': '1d',
|
95
|
+
'1w': '1w',
|
96
|
+
'1M': '1m',
|
97
|
+
},
|
98
|
+
'version': 'v2',
|
99
|
+
'urls': {
|
100
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/112027508-47984600-8b48-11eb-9e17-d26459cc36c6.jpg',
|
101
|
+
'api': {
|
102
|
+
'rest': 'https://ascendex.com',
|
103
|
+
},
|
104
|
+
'test': {
|
105
|
+
'rest': 'https://api-test.ascendex-sandbox.com',
|
106
|
+
},
|
107
|
+
'www': 'https://ascendex.com',
|
108
|
+
'doc': [
|
109
|
+
'https://ascendex.github.io/ascendex-pro-api/#ascendex-pro-api-documentation',
|
110
|
+
],
|
111
|
+
'fees': 'https://ascendex.com/en/feerate/transactionfee-traderate',
|
112
|
+
'referral': {
|
113
|
+
'url': 'https://ascendex.com/en-us/register?inviteCode=EL6BXBQM',
|
114
|
+
'discount': 0.25,
|
115
|
+
},
|
116
|
+
},
|
117
|
+
'api': {
|
118
|
+
'v1': {
|
119
|
+
'public': {
|
120
|
+
'get': {
|
121
|
+
'assets': 1,
|
122
|
+
'products': 1,
|
123
|
+
'ticker': 1,
|
124
|
+
'barhist/info': 1,
|
125
|
+
'barhist': 1,
|
126
|
+
'depth': 1,
|
127
|
+
'trades': 1,
|
128
|
+
'cash/assets': 1, // not documented
|
129
|
+
'cash/products': 1, // not documented
|
130
|
+
'margin/assets': 1, // not documented
|
131
|
+
'margin/products': 1, // not documented
|
132
|
+
'futures/collateral': 1,
|
133
|
+
'futures/contracts': 1,
|
134
|
+
'futures/ref-px': 1,
|
135
|
+
'futures/market-data': 1,
|
136
|
+
'futures/funding-rates': 1,
|
137
|
+
'risk-limit-info': 1,
|
138
|
+
},
|
139
|
+
},
|
140
|
+
'private': {
|
141
|
+
'get': {
|
142
|
+
'info': 1,
|
143
|
+
'wallet/transactions': 1,
|
144
|
+
'wallet/deposit/address': 1, // not documented
|
145
|
+
'data/balance/snapshot': 1,
|
146
|
+
'data/balance/history': 1,
|
147
|
+
},
|
148
|
+
'accountCategory': {
|
149
|
+
'get': {
|
150
|
+
'balance': 1,
|
151
|
+
'order/open': 1,
|
152
|
+
'order/status': 1,
|
153
|
+
'order/hist/current': 1,
|
154
|
+
'risk': 1,
|
155
|
+
},
|
156
|
+
'post': {
|
157
|
+
'order': 1,
|
158
|
+
'order/batch': 1,
|
159
|
+
},
|
160
|
+
'delete': {
|
161
|
+
'order': 1,
|
162
|
+
'order/all': 1,
|
163
|
+
'order/batch': 1,
|
164
|
+
},
|
165
|
+
},
|
166
|
+
'accountGroup': {
|
167
|
+
'get': {
|
168
|
+
'cash/balance': 1,
|
169
|
+
'margin/balance': 1,
|
170
|
+
'margin/risk': 1,
|
171
|
+
'futures/collateral-balance': 1,
|
172
|
+
'futures/position': 1,
|
173
|
+
'futures/risk': 1,
|
174
|
+
'futures/funding-payments': 1,
|
175
|
+
'order/hist': 1,
|
176
|
+
'spot/fee': 1,
|
177
|
+
},
|
178
|
+
'post': {
|
179
|
+
'transfer': 1,
|
180
|
+
'futures/transfer/deposit': 1,
|
181
|
+
'futures/transfer/withdraw': 1,
|
182
|
+
},
|
183
|
+
},
|
184
|
+
},
|
185
|
+
},
|
186
|
+
'v2': {
|
187
|
+
'public': {
|
188
|
+
'get': {
|
189
|
+
'assets': 1,
|
190
|
+
'futures/contract': 1,
|
191
|
+
'futures/collateral': 1,
|
192
|
+
'futures/pricing-data': 1,
|
193
|
+
},
|
194
|
+
},
|
195
|
+
'private': {
|
196
|
+
'get': {
|
197
|
+
'account/info': 1,
|
198
|
+
},
|
199
|
+
'accountGroup': {
|
200
|
+
'get': {
|
201
|
+
'order/hist': 1,
|
202
|
+
'futures/position': 1,
|
203
|
+
'futures/free-margin': 1,
|
204
|
+
'futures/order/hist/current': 1,
|
205
|
+
'futures/order/open': 1,
|
206
|
+
'futures/order/status': 1,
|
207
|
+
},
|
208
|
+
'post': {
|
209
|
+
'futures/isolated-position-margin': 1,
|
210
|
+
'futures/margin-type': 1,
|
211
|
+
'futures/leverage': 1,
|
212
|
+
'futures/transfer/deposit': 1,
|
213
|
+
'futures/transfer/withdraw': 1,
|
214
|
+
'futures/order': 1,
|
215
|
+
'futures/order/batch': 1,
|
216
|
+
'futures/order/open': 1,
|
217
|
+
'subuser/subuser-transfer': 1,
|
218
|
+
'subuser/subuser-transfer-hist': 1,
|
219
|
+
},
|
220
|
+
'delete': {
|
221
|
+
'futures/order': 1,
|
222
|
+
'futures/order/batch': 1,
|
223
|
+
'futures/order/all': 1,
|
224
|
+
},
|
225
|
+
},
|
226
|
+
},
|
227
|
+
},
|
228
|
+
},
|
229
|
+
'fees': {
|
230
|
+
'trading': {
|
231
|
+
'feeSide': 'get',
|
232
|
+
'tierBased': true,
|
233
|
+
'percentage': true,
|
234
|
+
'taker': this.parseNumber ('0.002'),
|
235
|
+
'maker': this.parseNumber ('0.002'),
|
236
|
+
},
|
237
|
+
},
|
238
|
+
'precisionMode': TICK_SIZE,
|
239
|
+
'options': {
|
240
|
+
'account-category': 'cash', // 'cash', 'margin', 'futures' // obsolete
|
241
|
+
'account-group': undefined,
|
242
|
+
'fetchClosedOrders': {
|
243
|
+
'method': 'v1PrivateAccountGroupGetOrderHist', // 'v1PrivateAccountGroupGetAccountCategoryOrderHistCurrent'
|
244
|
+
},
|
245
|
+
'defaultType': 'spot', // 'spot', 'margin', 'swap'
|
246
|
+
'accountsByType': {
|
247
|
+
'spot': 'cash',
|
248
|
+
'future': 'futures',
|
249
|
+
'margin': 'margin',
|
250
|
+
},
|
251
|
+
'transfer': {
|
252
|
+
'fillResponseFromRequest': true,
|
253
|
+
},
|
254
|
+
},
|
255
|
+
'exceptions': {
|
256
|
+
'exact': {
|
257
|
+
// not documented
|
258
|
+
'1900': BadRequest, // {"code":1900,"message":"Invalid Http Request Input"}
|
259
|
+
'2100': AuthenticationError, // {"code":2100,"message":"ApiKeyFailure"}
|
260
|
+
'5002': BadSymbol, // {"code":5002,"message":"Invalid Symbol"}
|
261
|
+
'6001': BadSymbol, // {"code":6001,"message":"Trading is disabled on symbol."}
|
262
|
+
'6010': InsufficientFunds, // {'code': 6010, 'message': 'Not enough balance.'}
|
263
|
+
'60060': InvalidOrder, // { 'code': 60060, 'message': 'The order is already filled or canceled.' }
|
264
|
+
'600503': InvalidOrder, // {"code":600503,"message":"Notional is too small."}
|
265
|
+
// documented
|
266
|
+
'100001': BadRequest, // INVALID_HTTP_INPUT Http request is invalid
|
267
|
+
'100002': BadRequest, // DATA_NOT_AVAILABLE Some required data is missing
|
268
|
+
'100003': BadRequest, // KEY_CONFLICT The same key exists already
|
269
|
+
'100004': BadRequest, // INVALID_REQUEST_DATA The HTTP request contains invalid field or argument
|
270
|
+
'100005': BadRequest, // INVALID_WS_REQUEST_DATA Websocket request contains invalid field or argument
|
271
|
+
'100006': BadRequest, // INVALID_ARGUMENT The arugment is invalid
|
272
|
+
'100007': BadRequest, // ENCRYPTION_ERROR Something wrong with data encryption
|
273
|
+
'100008': BadSymbol, // SYMBOL_ERROR Symbol does not exist or not valid for the request
|
274
|
+
'100009': AuthenticationError, // AUTHORIZATION_NEEDED Authorization is require for the API access or request
|
275
|
+
'100010': BadRequest, // INVALID_OPERATION The action is invalid or not allowed for the account
|
276
|
+
'100011': BadRequest, // INVALID_TIMESTAMP Not a valid timestamp
|
277
|
+
'100012': BadRequest, // INVALID_STR_FORMAT String format does not
|
278
|
+
'100013': BadRequest, // INVALID_NUM_FORMAT Invalid number input
|
279
|
+
'100101': ExchangeError, // UNKNOWN_ERROR Some unknown error
|
280
|
+
'150001': BadRequest, // INVALID_JSON_FORMAT Require a valid json object
|
281
|
+
'200001': AuthenticationError, // AUTHENTICATION_FAILED Authorization failed
|
282
|
+
'200002': ExchangeError, // TOO_MANY_ATTEMPTS Tried and failed too many times
|
283
|
+
'200003': ExchangeError, // ACCOUNT_NOT_FOUND Account not exist
|
284
|
+
'200004': ExchangeError, // ACCOUNT_NOT_SETUP Account not setup properly
|
285
|
+
'200005': ExchangeError, // ACCOUNT_ALREADY_EXIST Account already exist
|
286
|
+
'200006': ExchangeError, // ACCOUNT_ERROR Some error related with error
|
287
|
+
'200007': ExchangeError, // CODE_NOT_FOUND
|
288
|
+
'200008': ExchangeError, // CODE_EXPIRED Code expired
|
289
|
+
'200009': ExchangeError, // CODE_MISMATCH Code does not match
|
290
|
+
'200010': AuthenticationError, // PASSWORD_ERROR Wrong assword
|
291
|
+
'200011': ExchangeError, // CODE_GEN_FAILED Do not generate required code promptly
|
292
|
+
'200012': ExchangeError, // FAKE_COKE_VERIFY
|
293
|
+
'200013': ExchangeError, // SECURITY_ALERT Provide security alert message
|
294
|
+
'200014': PermissionDenied, // RESTRICTED_ACCOUNT Account is restricted for certain activity, such as trading, or withdraw.
|
295
|
+
'200015': PermissionDenied, // PERMISSION_DENIED No enough permission for the operation
|
296
|
+
'300001': InvalidOrder, // INVALID_PRICE Order price is invalid
|
297
|
+
'300002': InvalidOrder, // INVALID_QTY Order size is invalid
|
298
|
+
'300003': InvalidOrder, // INVALID_SIDE Order side is invalid
|
299
|
+
'300004': InvalidOrder, // INVALID_NOTIONAL Notional is too small or too large
|
300
|
+
'300005': InvalidOrder, // INVALID_TYPE Order typs is invalid
|
301
|
+
'300006': InvalidOrder, // INVALID_ORDER_ID Order id is invalid
|
302
|
+
'300007': InvalidOrder, // INVALID_TIME_IN_FORCE Time In Force in order request is invalid
|
303
|
+
'300008': InvalidOrder, // INVALID_ORDER_PARAMETER Some order parameter is invalid
|
304
|
+
'300009': InvalidOrder, // TRADING_VIOLATION Trading violation on account or asset
|
305
|
+
'300011': InsufficientFunds, // INVALID_BALANCE No enough account or asset balance for the trading
|
306
|
+
'300012': BadSymbol, // INVALID_PRODUCT Not a valid product supported by exchange
|
307
|
+
'300013': InvalidOrder, // INVALID_BATCH_ORDER Some or all orders are invalid in batch order request
|
308
|
+
'300014': InvalidOrder, // {"code":300014,"message":"Order price doesn't conform to the required tick size: 0.1","reason":"TICK_SIZE_VIOLATION"}
|
309
|
+
'300020': InvalidOrder, // TRADING_RESTRICTED There is some trading restriction on account or asset
|
310
|
+
'300021': InvalidOrder, // TRADING_DISABLED Trading is disabled on account or asset
|
311
|
+
'300031': InvalidOrder, // NO_MARKET_PRICE No market price for market type order trading
|
312
|
+
'310001': InsufficientFunds, // INVALID_MARGIN_BALANCE No enough margin balance
|
313
|
+
'310002': InvalidOrder, // INVALID_MARGIN_ACCOUNT Not a valid account for margin trading
|
314
|
+
'310003': InvalidOrder, // MARGIN_TOO_RISKY Leverage is too high
|
315
|
+
'310004': BadSymbol, // INVALID_MARGIN_ASSET This asset does not support margin trading
|
316
|
+
'310005': InvalidOrder, // INVALID_REFERENCE_PRICE There is no valid reference price
|
317
|
+
'510001': ExchangeError, // SERVER_ERROR Something wrong with server.
|
318
|
+
'900001': ExchangeError, // HUMAN_CHALLENGE Human change do not pass
|
319
|
+
},
|
320
|
+
'broad': {},
|
321
|
+
},
|
322
|
+
'commonCurrencies': {
|
323
|
+
'BOND': 'BONDED',
|
324
|
+
'BTCBEAR': 'BEAR',
|
325
|
+
'BTCBULL': 'BULL',
|
326
|
+
'BYN': 'BeyondFi',
|
327
|
+
'PLN': 'Pollen',
|
328
|
+
},
|
329
|
+
});
|
330
|
+
}
|
331
|
+
|
332
|
+
getAccount (params = {}) {
|
333
|
+
// get current or provided bitmax sub-account
|
334
|
+
const account = this.safeValue (params, 'account', this.options['account']);
|
335
|
+
return account.toLowerCase ().capitalize ();
|
336
|
+
}
|
337
|
+
|
338
|
+
async fetchCurrencies (params = {}) {
|
339
|
+
const assets = await this.v1PublicGetAssets (params);
|
340
|
+
//
|
341
|
+
// {
|
342
|
+
// "code":0,
|
343
|
+
// "data":[
|
344
|
+
// {
|
345
|
+
// "assetCode" : "LTCBULL",
|
346
|
+
// "assetName" : "3X Long LTC Token",
|
347
|
+
// "precisionScale" : 9,
|
348
|
+
// "nativeScale" : 4,
|
349
|
+
// "withdrawalFee" : "0.2",
|
350
|
+
// "minWithdrawalAmt" : "1.0",
|
351
|
+
// "status" : "Normal"
|
352
|
+
// },
|
353
|
+
// ]
|
354
|
+
// }
|
355
|
+
//
|
356
|
+
const margin = await this.v1PublicGetMarginAssets (params);
|
357
|
+
//
|
358
|
+
// {
|
359
|
+
// "code":0,
|
360
|
+
// "data":[
|
361
|
+
// {
|
362
|
+
// "assetCode":"BTT",
|
363
|
+
// "borrowAssetCode":"BTT-B",
|
364
|
+
// "interestAssetCode":"BTT-I",
|
365
|
+
// "nativeScale":0,
|
366
|
+
// "numConfirmations":1,
|
367
|
+
// "withdrawFee":"100.0",
|
368
|
+
// "minWithdrawalAmt":"1000.0",
|
369
|
+
// "statusCode":"Normal",
|
370
|
+
// "statusMessage":"",
|
371
|
+
// "interestRate":"0.001"
|
372
|
+
// }
|
373
|
+
// ]
|
374
|
+
// }
|
375
|
+
//
|
376
|
+
const cash = await this.v1PublicGetCashAssets (params);
|
377
|
+
//
|
378
|
+
// {
|
379
|
+
// "code":0,
|
380
|
+
// "data":[
|
381
|
+
// {
|
382
|
+
// "assetCode":"LTCBULL",
|
383
|
+
// "nativeScale":4,
|
384
|
+
// "numConfirmations":20,
|
385
|
+
// "withdrawFee":"0.2",
|
386
|
+
// "minWithdrawalAmt":"1.0",
|
387
|
+
// "statusCode":"Normal",
|
388
|
+
// "statusMessage":""
|
389
|
+
// }
|
390
|
+
// ]
|
391
|
+
// }
|
392
|
+
//
|
393
|
+
const assetsData = this.safeValue (assets, 'data', []);
|
394
|
+
const marginData = this.safeValue (margin, 'data', []);
|
395
|
+
const cashData = this.safeValue (cash, 'data', []);
|
396
|
+
const assetsById = this.indexBy (assetsData, 'assetCode');
|
397
|
+
const marginById = this.indexBy (marginData, 'assetCode');
|
398
|
+
const cashById = this.indexBy (cashData, 'assetCode');
|
399
|
+
const dataById = this.deepExtend (assetsById, marginById, cashById);
|
400
|
+
const ids = Object.keys (dataById);
|
401
|
+
const result = {};
|
402
|
+
for (let i = 0; i < ids.length; i++) {
|
403
|
+
const id = ids[i];
|
404
|
+
const currency = dataById[id];
|
405
|
+
const code = this.safeCurrencyCode (id);
|
406
|
+
const scale = this.safeString2 (currency, 'precisionScale', 'nativeScale');
|
407
|
+
const precision = this.parseNumber (this.parsePrecision (scale));
|
408
|
+
// why would the exchange API have different names for the same field
|
409
|
+
const fee = this.safeNumber2 (currency, 'withdrawFee', 'withdrawalFee');
|
410
|
+
const status = this.safeString2 (currency, 'status', 'statusCode');
|
411
|
+
const active = (status === 'Normal');
|
412
|
+
const margin = ('borrowAssetCode' in currency);
|
413
|
+
result[code] = {
|
414
|
+
'id': id,
|
415
|
+
'code': code,
|
416
|
+
'info': currency,
|
417
|
+
'type': undefined,
|
418
|
+
'margin': margin,
|
419
|
+
'name': this.safeString (currency, 'assetName'),
|
420
|
+
'active': active,
|
421
|
+
'deposit': undefined,
|
422
|
+
'withdraw': undefined,
|
423
|
+
'fee': fee,
|
424
|
+
'precision': precision,
|
425
|
+
'limits': {
|
426
|
+
'amount': {
|
427
|
+
'min': precision,
|
428
|
+
'max': undefined,
|
429
|
+
},
|
430
|
+
'withdraw': {
|
431
|
+
'min': this.safeNumber (currency, 'minWithdrawalAmt'),
|
432
|
+
'max': undefined,
|
433
|
+
},
|
434
|
+
},
|
435
|
+
};
|
436
|
+
}
|
437
|
+
return result;
|
438
|
+
}
|
439
|
+
|
440
|
+
async fetchMarkets (params = {}) {
|
441
|
+
const products = await this.v1PublicGetProducts (params);
|
442
|
+
//
|
443
|
+
// {
|
444
|
+
// "code":0,
|
445
|
+
// "data":[
|
446
|
+
// {
|
447
|
+
// "symbol":"LBA/BTC",
|
448
|
+
// "baseAsset":"LBA",
|
449
|
+
// "quoteAsset":"BTC",
|
450
|
+
// "status":"Normal",
|
451
|
+
// "minNotional":"0.000625",
|
452
|
+
// "maxNotional":"6.25",
|
453
|
+
// "marginTradable":false,
|
454
|
+
// "commissionType":"Quote",
|
455
|
+
// "commissionReserveRate":"0.001",
|
456
|
+
// "tickSize":"0.000000001",
|
457
|
+
// "lotSize":"1"
|
458
|
+
// },
|
459
|
+
// ]
|
460
|
+
// }
|
461
|
+
//
|
462
|
+
const cash = await this.v1PublicGetCashProducts (params);
|
463
|
+
//
|
464
|
+
// {
|
465
|
+
// "code":0,
|
466
|
+
// "data":[
|
467
|
+
// {
|
468
|
+
// "symbol":"QTUM/BTC",
|
469
|
+
// "domain":"BTC",
|
470
|
+
// "tradingStartTime":1569506400000,
|
471
|
+
// "collapseDecimals":"0.0001,0.000001,0.00000001",
|
472
|
+
// "minQty":"0.000000001",
|
473
|
+
// "maxQty":"1000000000",
|
474
|
+
// "minNotional":"0.000625",
|
475
|
+
// "maxNotional":"12.5",
|
476
|
+
// "statusCode":"Normal",
|
477
|
+
// "statusMessage":"",
|
478
|
+
// "tickSize":"0.00000001",
|
479
|
+
// "useTick":false,
|
480
|
+
// "lotSize":"0.1",
|
481
|
+
// "useLot":false,
|
482
|
+
// "commissionType":"Quote",
|
483
|
+
// "commissionReserveRate":"0.001",
|
484
|
+
// "qtyScale":1,
|
485
|
+
// "priceScale":8,
|
486
|
+
// "notionalScale":4
|
487
|
+
// }
|
488
|
+
// ]
|
489
|
+
// }
|
490
|
+
//
|
491
|
+
const perpetuals = await this.v2PublicGetFuturesContract (params);
|
492
|
+
//
|
493
|
+
// {
|
494
|
+
// "code":0,
|
495
|
+
// "data":[
|
496
|
+
// {
|
497
|
+
// "symbol":"BTC-PERP",
|
498
|
+
// "status":"Normal",
|
499
|
+
// "displayName":"BTCUSDT",
|
500
|
+
// "settlementAsset":"USDT",
|
501
|
+
// "underlying":"BTC/USDT",
|
502
|
+
// "tradingStartTime":1579701600000,
|
503
|
+
// "priceFilter":{"minPrice":"1","maxPrice":"1000000","tickSize":"1"},
|
504
|
+
// "lotSizeFilter":{"minQty":"0.0001","maxQty":"1000000000","lotSize":"0.0001"},
|
505
|
+
// "commissionType":"Quote",
|
506
|
+
// "commissionReserveRate":"0.001",
|
507
|
+
// "marketOrderPriceMarkup":"0.03",
|
508
|
+
// "marginRequirements":[
|
509
|
+
// {"positionNotionalLowerBound":"0","positionNotionalUpperBound":"50000","initialMarginRate":"0.01","maintenanceMarginRate":"0.006"},
|
510
|
+
// {"positionNotionalLowerBound":"50000","positionNotionalUpperBound":"200000","initialMarginRate":"0.02","maintenanceMarginRate":"0.012"},
|
511
|
+
// {"positionNotionalLowerBound":"200000","positionNotionalUpperBound":"2000000","initialMarginRate":"0.04","maintenanceMarginRate":"0.024"},
|
512
|
+
// {"positionNotionalLowerBound":"2000000","positionNotionalUpperBound":"20000000","initialMarginRate":"0.1","maintenanceMarginRate":"0.06"},
|
513
|
+
// {"positionNotionalLowerBound":"20000000","positionNotionalUpperBound":"40000000","initialMarginRate":"0.2","maintenanceMarginRate":"0.12"},
|
514
|
+
// {"positionNotionalLowerBound":"40000000","positionNotionalUpperBound":"1000000000","initialMarginRate":"0.333333","maintenanceMarginRate":"0.2"}
|
515
|
+
// ]
|
516
|
+
// }
|
517
|
+
// ]
|
518
|
+
// }
|
519
|
+
//
|
520
|
+
const productsData = this.safeValue (products, 'data', []);
|
521
|
+
const productsById = this.indexBy (productsData, 'symbol');
|
522
|
+
const cashData = this.safeValue (cash, 'data', []);
|
523
|
+
const perpetualsData = this.safeValue (perpetuals, 'data', []);
|
524
|
+
const cashAndPerpetualsData = this.arrayConcat (cashData, perpetualsData);
|
525
|
+
const cashAndPerpetualsById = this.indexBy (cashAndPerpetualsData, 'symbol');
|
526
|
+
const dataById = this.deepExtend (productsById, cashAndPerpetualsById);
|
527
|
+
const ids = Object.keys (dataById);
|
528
|
+
const result = [];
|
529
|
+
for (let i = 0; i < ids.length; i++) {
|
530
|
+
const id = ids[i];
|
531
|
+
const market = dataById[id];
|
532
|
+
let baseId = this.safeString (market, 'baseAsset');
|
533
|
+
let quoteId = this.safeString (market, 'quoteAsset');
|
534
|
+
const settleId = this.safeValue (market, 'settlementAsset');
|
535
|
+
let base = this.safeCurrencyCode (baseId);
|
536
|
+
let quote = this.safeCurrencyCode (quoteId);
|
537
|
+
const settle = this.safeCurrencyCode (settleId);
|
538
|
+
const status = this.safeString (market, 'status');
|
539
|
+
const spot = settle === undefined;
|
540
|
+
const swap = !spot;
|
541
|
+
const linear = swap ? true : undefined;
|
542
|
+
let minQty = this.safeNumber (market, 'minQty');
|
543
|
+
let maxQty = this.safeNumber (market, 'maxQty');
|
544
|
+
let minPrice = this.safeNumber (market, 'tickSize');
|
545
|
+
let maxPrice = undefined;
|
546
|
+
let symbol = base + '/' + quote;
|
547
|
+
if (swap) {
|
548
|
+
const lotSizeFilter = this.safeValue (market, 'lotSizeFilter');
|
549
|
+
minQty = this.safeNumber (lotSizeFilter, 'minQty');
|
550
|
+
maxQty = this.safeNumber (lotSizeFilter, 'maxQty');
|
551
|
+
const priceFilter = this.safeValue (market, 'priceFilter');
|
552
|
+
minPrice = this.safeNumber (priceFilter, 'minPrice');
|
553
|
+
maxPrice = this.safeNumber (priceFilter, 'maxPrice');
|
554
|
+
const underlying = this.safeString (market, 'underlying');
|
555
|
+
const parts = underlying.split ('/');
|
556
|
+
baseId = this.safeString (parts, 0);
|
557
|
+
quoteId = this.safeString (parts, 1);
|
558
|
+
base = this.safeCurrencyCode (baseId);
|
559
|
+
quote = this.safeCurrencyCode (quoteId);
|
560
|
+
symbol = base + '/' + quote + ':' + settle;
|
561
|
+
}
|
562
|
+
const fee = this.safeNumber (market, 'commissionReserveRate');
|
563
|
+
const marginTradable = this.safeValue (market, 'marginTradable', false);
|
564
|
+
result.push ({
|
565
|
+
'id': id,
|
566
|
+
'symbol': symbol,
|
567
|
+
'base': base,
|
568
|
+
'quote': quote,
|
569
|
+
'settle': settle,
|
570
|
+
'baseId': baseId,
|
571
|
+
'quoteId': quoteId,
|
572
|
+
'settleId': settleId,
|
573
|
+
'type': swap ? 'swap' : 'spot',
|
574
|
+
'spot': spot,
|
575
|
+
'margin': spot ? marginTradable : undefined,
|
576
|
+
'swap': swap,
|
577
|
+
'future': false,
|
578
|
+
'option': false,
|
579
|
+
'active': (status === 'Normal'),
|
580
|
+
'contract': swap,
|
581
|
+
'linear': linear,
|
582
|
+
'inverse': swap ? !linear : undefined,
|
583
|
+
'taker': fee,
|
584
|
+
'maker': fee,
|
585
|
+
'contractSize': swap ? this.parseNumber ('1') : undefined,
|
586
|
+
'expiry': undefined,
|
587
|
+
'expiryDatetime': undefined,
|
588
|
+
'strike': undefined,
|
589
|
+
'optionType': undefined,
|
590
|
+
'precision': {
|
591
|
+
'amount': this.safeNumber (market, 'lotSize'),
|
592
|
+
'price': this.safeNumber (market, 'tickSize'),
|
593
|
+
},
|
594
|
+
'limits': {
|
595
|
+
'leverage': {
|
596
|
+
'min': undefined,
|
597
|
+
'max': undefined,
|
598
|
+
},
|
599
|
+
'amount': {
|
600
|
+
'min': minQty,
|
601
|
+
'max': maxQty,
|
602
|
+
},
|
603
|
+
'price': {
|
604
|
+
'min': minPrice,
|
605
|
+
'max': maxPrice,
|
606
|
+
},
|
607
|
+
'cost': {
|
608
|
+
'min': this.safeNumber (market, 'minNotional'),
|
609
|
+
'max': this.safeNumber (market, 'maxNotional'),
|
610
|
+
},
|
611
|
+
},
|
612
|
+
'info': market,
|
613
|
+
});
|
614
|
+
}
|
615
|
+
return result;
|
616
|
+
}
|
617
|
+
|
618
|
+
async fetchAccounts (params = {}) {
|
619
|
+
let accountGroup = this.safeString (this.options, 'account-group');
|
620
|
+
let response = undefined;
|
621
|
+
if (accountGroup === undefined) {
|
622
|
+
response = await this.v1PrivateGetInfo (params);
|
623
|
+
//
|
624
|
+
// {
|
625
|
+
// "code":0,
|
626
|
+
// "data":{
|
627
|
+
// "email":"igor.kroitor@gmail.com",
|
628
|
+
// "accountGroup":8,
|
629
|
+
// "viewPermission":true,
|
630
|
+
// "tradePermission":true,
|
631
|
+
// "transferPermission":true,
|
632
|
+
// "cashAccount":["cshrHKLZCjlZ2ejqkmvIHHtPmLYqdnda"],
|
633
|
+
// "marginAccount":["martXoh1v1N3EMQC5FDtSj5VHso8aI2Z"],
|
634
|
+
// "futuresAccount":["futc9r7UmFJAyBY2rE3beA2JFxav2XFF"],
|
635
|
+
// "userUID":"U6491137460"
|
636
|
+
// }
|
637
|
+
// }
|
638
|
+
//
|
639
|
+
const data = this.safeValue (response, 'data', {});
|
640
|
+
accountGroup = this.safeString (data, 'accountGroup');
|
641
|
+
this.options['account-group'] = accountGroup;
|
642
|
+
}
|
643
|
+
return [
|
644
|
+
{
|
645
|
+
'id': accountGroup,
|
646
|
+
'type': undefined,
|
647
|
+
'currency': undefined,
|
648
|
+
'info': response,
|
649
|
+
},
|
650
|
+
];
|
651
|
+
}
|
652
|
+
|
653
|
+
parseBalance (response) {
|
654
|
+
const result = {
|
655
|
+
'info': response,
|
656
|
+
'timestamp': undefined,
|
657
|
+
'datetime': undefined,
|
658
|
+
};
|
659
|
+
const balances = this.safeValue (response, 'data', []);
|
660
|
+
for (let i = 0; i < balances.length; i++) {
|
661
|
+
const balance = balances[i];
|
662
|
+
const code = this.safeCurrencyCode (this.safeString (balance, 'asset'));
|
663
|
+
const account = this.account ();
|
664
|
+
account['free'] = this.safeString (balance, 'availableBalance');
|
665
|
+
account['total'] = this.safeString (balance, 'totalBalance');
|
666
|
+
result[code] = account;
|
667
|
+
}
|
668
|
+
return this.safeBalance (result);
|
669
|
+
}
|
670
|
+
|
671
|
+
parseSwapBalance (response) {
|
672
|
+
const timestamp = this.milliseconds ();
|
673
|
+
const result = {
|
674
|
+
'info': response,
|
675
|
+
'timestamp': timestamp,
|
676
|
+
'datetime': this.iso8601 (timestamp),
|
677
|
+
};
|
678
|
+
const data = this.safeValue (response, 'data', {});
|
679
|
+
const collaterals = this.safeValue (data, 'collaterals', []);
|
680
|
+
for (let i = 0; i < collaterals.length; i++) {
|
681
|
+
const balance = collaterals[i];
|
682
|
+
const code = this.safeCurrencyCode (this.safeString (balance, 'asset'));
|
683
|
+
const account = this.account ();
|
684
|
+
account['total'] = this.safeString (balance, 'balance');
|
685
|
+
result[code] = account;
|
686
|
+
}
|
687
|
+
return this.safeBalance (result);
|
688
|
+
}
|
689
|
+
|
690
|
+
async fetchBalance (params = {}) {
|
691
|
+
await this.loadMarkets ();
|
692
|
+
await this.loadAccounts ();
|
693
|
+
const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchBalance', undefined, params);
|
694
|
+
const options = this.safeValue (this.options, 'fetchBalance', {});
|
695
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
696
|
+
const accountCategory = this.safeString (accountsByType, marketType, 'cash');
|
697
|
+
const account = this.safeValue (this.accounts, 0, {});
|
698
|
+
const accountGroup = this.safeString (account, 'id');
|
699
|
+
const request = {
|
700
|
+
'account-group': accountGroup,
|
701
|
+
};
|
702
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountCategoryGetBalance');
|
703
|
+
const method = this.getSupportedMapping (marketType, {
|
704
|
+
'spot': defaultMethod,
|
705
|
+
'margin': defaultMethod,
|
706
|
+
'swap': 'v2PrivateAccountGroupGetFuturesPosition',
|
707
|
+
});
|
708
|
+
if (accountCategory === 'cash') {
|
709
|
+
request['account-category'] = accountCategory;
|
710
|
+
}
|
711
|
+
const response = await this[method] (this.extend (request, query));
|
712
|
+
//
|
713
|
+
// cash
|
714
|
+
//
|
715
|
+
// {
|
716
|
+
// 'code': 0,
|
717
|
+
// 'data': [
|
718
|
+
// {
|
719
|
+
// 'asset': 'BCHSV',
|
720
|
+
// 'totalBalance': '64.298000048',
|
721
|
+
// 'availableBalance': '64.298000048',
|
722
|
+
// },
|
723
|
+
// ]
|
724
|
+
// }
|
725
|
+
//
|
726
|
+
// margin
|
727
|
+
//
|
728
|
+
// {
|
729
|
+
// 'code': 0,
|
730
|
+
// 'data': [
|
731
|
+
// {
|
732
|
+
// 'asset': 'BCHSV',
|
733
|
+
// 'totalBalance': '64.298000048',
|
734
|
+
// 'availableBalance': '64.298000048',
|
735
|
+
// 'borrowed': '0',
|
736
|
+
// 'interest': '0',
|
737
|
+
// },
|
738
|
+
// ]
|
739
|
+
// }
|
740
|
+
//
|
741
|
+
// swap
|
742
|
+
//
|
743
|
+
// {
|
744
|
+
// "code": 0,
|
745
|
+
// "data": {
|
746
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
747
|
+
// "ac": "FUTURES",
|
748
|
+
// "collaterals": [
|
749
|
+
// {"asset":"ADA","balance":"0.355803","referencePrice":"1.05095","discountFactor":"0.9"},
|
750
|
+
// {"asset":"USDT","balance":"0.000014519","referencePrice":"1","discountFactor":"1"}
|
751
|
+
// ],
|
752
|
+
// }j
|
753
|
+
// }
|
754
|
+
//
|
755
|
+
if (marketType === 'swap') {
|
756
|
+
return this.parseSwapBalance (response);
|
757
|
+
} else {
|
758
|
+
return this.parseBalance (response);
|
759
|
+
}
|
760
|
+
}
|
761
|
+
|
762
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
763
|
+
await this.loadMarkets ();
|
764
|
+
const market = this.market (symbol);
|
765
|
+
const request = {
|
766
|
+
'symbol': market['id'],
|
767
|
+
};
|
768
|
+
const response = await this.v1PublicGetDepth (this.extend (request, params));
|
769
|
+
//
|
770
|
+
// {
|
771
|
+
// "code":0,
|
772
|
+
// "data":{
|
773
|
+
// "m":"depth-snapshot",
|
774
|
+
// "symbol":"BTC-PERP",
|
775
|
+
// "data":{
|
776
|
+
// "ts":1590223998202,
|
777
|
+
// "seqnum":115444921,
|
778
|
+
// "asks":[
|
779
|
+
// ["9207.5","18.2383"],
|
780
|
+
// ["9207.75","18.8235"],
|
781
|
+
// ["9208","10.7873"],
|
782
|
+
// ],
|
783
|
+
// "bids":[
|
784
|
+
// ["9207.25","0.4009"],
|
785
|
+
// ["9207","0.003"],
|
786
|
+
// ["9206.5","0.003"],
|
787
|
+
// ]
|
788
|
+
// }
|
789
|
+
// }
|
790
|
+
// }
|
791
|
+
//
|
792
|
+
const data = this.safeValue (response, 'data', {});
|
793
|
+
const orderbook = this.safeValue (data, 'data', {});
|
794
|
+
const timestamp = this.safeInteger (orderbook, 'ts');
|
795
|
+
const result = this.parseOrderBook (orderbook, symbol, timestamp);
|
796
|
+
result['nonce'] = this.safeInteger (orderbook, 'seqnum');
|
797
|
+
return result;
|
798
|
+
}
|
799
|
+
|
800
|
+
parseTicker (ticker, market = undefined) {
|
801
|
+
//
|
802
|
+
// {
|
803
|
+
// "symbol":"QTUM/BTC",
|
804
|
+
// "open":"0.00016537",
|
805
|
+
// "close":"0.00019077",
|
806
|
+
// "high":"0.000192",
|
807
|
+
// "low":"0.00016537",
|
808
|
+
// "volume":"846.6",
|
809
|
+
// "ask":["0.00018698","26.2"],
|
810
|
+
// "bid":["0.00018408","503.7"],
|
811
|
+
// "type":"spot"
|
812
|
+
// }
|
813
|
+
//
|
814
|
+
const timestamp = undefined;
|
815
|
+
const marketId = this.safeString (ticker, 'symbol');
|
816
|
+
const type = this.safeString (ticker, 'type');
|
817
|
+
const delimiter = (type === 'spot') ? '/' : undefined;
|
818
|
+
const symbol = this.safeSymbol (marketId, market, delimiter);
|
819
|
+
const close = this.safeString (ticker, 'close');
|
820
|
+
const bid = this.safeValue (ticker, 'bid', []);
|
821
|
+
const ask = this.safeValue (ticker, 'ask', []);
|
822
|
+
const open = this.safeString (ticker, 'open');
|
823
|
+
return this.safeTicker ({
|
824
|
+
'symbol': symbol,
|
825
|
+
'timestamp': timestamp,
|
826
|
+
'datetime': undefined,
|
827
|
+
'high': this.safeString (ticker, 'high'),
|
828
|
+
'low': this.safeString (ticker, 'low'),
|
829
|
+
'bid': this.safeString (bid, 0),
|
830
|
+
'bidVolume': this.safeString (bid, 1),
|
831
|
+
'ask': this.safeString (ask, 0),
|
832
|
+
'askVolume': this.safeString (ask, 1),
|
833
|
+
'vwap': undefined,
|
834
|
+
'open': open,
|
835
|
+
'close': close,
|
836
|
+
'last': close,
|
837
|
+
'previousClose': undefined, // previous day close
|
838
|
+
'change': undefined,
|
839
|
+
'percentage': undefined,
|
840
|
+
'average': undefined,
|
841
|
+
'baseVolume': this.safeString (ticker, 'volume'),
|
842
|
+
'quoteVolume': undefined,
|
843
|
+
'info': ticker,
|
844
|
+
}, market, false);
|
845
|
+
}
|
846
|
+
|
847
|
+
async fetchTicker (symbol, params = {}) {
|
848
|
+
await this.loadMarkets ();
|
849
|
+
const market = this.market (symbol);
|
850
|
+
const request = {
|
851
|
+
'symbol': market['id'],
|
852
|
+
};
|
853
|
+
const response = await this.v1PublicGetTicker (this.extend (request, params));
|
854
|
+
//
|
855
|
+
// {
|
856
|
+
// "code":0,
|
857
|
+
// "data":{
|
858
|
+
// "symbol":"BTC-PERP", // or "BTC/USDT"
|
859
|
+
// "open":"9073",
|
860
|
+
// "close":"9185.75",
|
861
|
+
// "high":"9185.75",
|
862
|
+
// "low":"9185.75",
|
863
|
+
// "volume":"576.8334",
|
864
|
+
// "ask":["9185.75","15.5863"],
|
865
|
+
// "bid":["9185.5","0.003"],
|
866
|
+
// "type":"derivatives", // or "spot"
|
867
|
+
// }
|
868
|
+
// }
|
869
|
+
//
|
870
|
+
const data = this.safeValue (response, 'data', {});
|
871
|
+
return this.parseTicker (data, market);
|
872
|
+
}
|
873
|
+
|
874
|
+
async fetchTickers (symbols = undefined, params = {}) {
|
875
|
+
await this.loadMarkets ();
|
876
|
+
const request = {};
|
877
|
+
if (symbols !== undefined) {
|
878
|
+
const marketIds = this.marketIds (symbols);
|
879
|
+
request['symbol'] = marketIds.join (',');
|
880
|
+
}
|
881
|
+
const response = await this.v1PublicGetTicker (this.extend (request, params));
|
882
|
+
//
|
883
|
+
// {
|
884
|
+
// "code":0,
|
885
|
+
// "data":[
|
886
|
+
// {
|
887
|
+
// "symbol":"QTUM/BTC",
|
888
|
+
// "open":"0.00016537",
|
889
|
+
// "close":"0.00019077",
|
890
|
+
// "high":"0.000192",
|
891
|
+
// "low":"0.00016537",
|
892
|
+
// "volume":"846.6",
|
893
|
+
// "ask":["0.00018698","26.2"],
|
894
|
+
// "bid":["0.00018408","503.7"],
|
895
|
+
// "type":"spot"
|
896
|
+
// }
|
897
|
+
// ]
|
898
|
+
// }
|
899
|
+
//
|
900
|
+
const data = this.safeValue (response, 'data', []);
|
901
|
+
return this.parseTickers (data, symbols);
|
902
|
+
}
|
903
|
+
|
904
|
+
parseOHLCV (ohlcv, market = undefined) {
|
905
|
+
//
|
906
|
+
// {
|
907
|
+
// "m":"bar",
|
908
|
+
// "s":"BTC/USDT",
|
909
|
+
// "data":{
|
910
|
+
// "i":"1",
|
911
|
+
// "ts":1590228000000,
|
912
|
+
// "o":"9139.59",
|
913
|
+
// "c":"9131.94",
|
914
|
+
// "h":"9139.99",
|
915
|
+
// "l":"9121.71",
|
916
|
+
// "v":"25.20648"
|
917
|
+
// }
|
918
|
+
// }
|
919
|
+
//
|
920
|
+
const data = this.safeValue (ohlcv, 'data', {});
|
921
|
+
return [
|
922
|
+
this.safeInteger (data, 'ts'),
|
923
|
+
this.safeNumber (data, 'o'),
|
924
|
+
this.safeNumber (data, 'h'),
|
925
|
+
this.safeNumber (data, 'l'),
|
926
|
+
this.safeNumber (data, 'c'),
|
927
|
+
this.safeNumber (data, 'v'),
|
928
|
+
];
|
929
|
+
}
|
930
|
+
|
931
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
932
|
+
await this.loadMarkets ();
|
933
|
+
const market = this.market (symbol);
|
934
|
+
const request = {
|
935
|
+
'symbol': market['id'],
|
936
|
+
'interval': this.timeframes[timeframe],
|
937
|
+
};
|
938
|
+
// if since and limit are not specified
|
939
|
+
// the exchange will return just 1 last candle by default
|
940
|
+
const duration = this.parseTimeframe (timeframe);
|
941
|
+
const options = this.safeValue (this.options, 'fetchOHLCV', {});
|
942
|
+
const defaultLimit = this.safeInteger (options, 'limit', 500);
|
943
|
+
if (since !== undefined) {
|
944
|
+
request['from'] = since;
|
945
|
+
if (limit === undefined) {
|
946
|
+
limit = defaultLimit;
|
947
|
+
} else {
|
948
|
+
limit = Math.min (limit, defaultLimit);
|
949
|
+
}
|
950
|
+
request['to'] = this.sum (since, limit * duration * 1000, 1);
|
951
|
+
} else if (limit !== undefined) {
|
952
|
+
request['n'] = limit; // max 500
|
953
|
+
}
|
954
|
+
const response = await this.v1PublicGetBarhist (this.extend (request, params));
|
955
|
+
//
|
956
|
+
// {
|
957
|
+
// "code":0,
|
958
|
+
// "data":[
|
959
|
+
// {
|
960
|
+
// "m":"bar",
|
961
|
+
// "s":"BTC/USDT",
|
962
|
+
// "data":{
|
963
|
+
// "i":"1",
|
964
|
+
// "ts":1590228000000,
|
965
|
+
// "o":"9139.59",
|
966
|
+
// "c":"9131.94",
|
967
|
+
// "h":"9139.99",
|
968
|
+
// "l":"9121.71",
|
969
|
+
// "v":"25.20648"
|
970
|
+
// }
|
971
|
+
// }
|
972
|
+
// ]
|
973
|
+
// }
|
974
|
+
//
|
975
|
+
const data = this.safeValue (response, 'data', []);
|
976
|
+
return this.parseOHLCVs (data, market, timeframe, since, limit);
|
977
|
+
}
|
978
|
+
|
979
|
+
parseTrade (trade, market = undefined) {
|
980
|
+
//
|
981
|
+
// public fetchTrades
|
982
|
+
//
|
983
|
+
// {
|
984
|
+
// "p":"9128.5", // price
|
985
|
+
// "q":"0.0030", // quantity
|
986
|
+
// "ts":1590229002385, // timestamp
|
987
|
+
// "bm":false, // if true, the buyer is the market maker, we only use this field to "define the side" of a public trade
|
988
|
+
// "seqnum":180143985289898554
|
989
|
+
// }
|
990
|
+
//
|
991
|
+
const timestamp = this.safeInteger (trade, 'ts');
|
992
|
+
const priceString = this.safeString2 (trade, 'price', 'p');
|
993
|
+
const amountString = this.safeString (trade, 'q');
|
994
|
+
const buyerIsMaker = this.safeValue (trade, 'bm', false);
|
995
|
+
const makerOrTaker = buyerIsMaker ? 'maker' : 'taker';
|
996
|
+
const side = buyerIsMaker ? 'buy' : 'sell';
|
997
|
+
market = this.safeMarket (undefined, market);
|
998
|
+
return this.safeTrade ({
|
999
|
+
'info': trade,
|
1000
|
+
'timestamp': timestamp,
|
1001
|
+
'datetime': this.iso8601 (timestamp),
|
1002
|
+
'symbol': market['symbol'],
|
1003
|
+
'id': undefined,
|
1004
|
+
'order': undefined,
|
1005
|
+
'type': undefined,
|
1006
|
+
'takerOrMaker': makerOrTaker,
|
1007
|
+
'side': side,
|
1008
|
+
'price': priceString,
|
1009
|
+
'amount': amountString,
|
1010
|
+
'cost': undefined,
|
1011
|
+
'fee': undefined,
|
1012
|
+
}, market);
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
1016
|
+
await this.loadMarkets ();
|
1017
|
+
const market = this.market (symbol);
|
1018
|
+
const request = {
|
1019
|
+
'symbol': market['id'],
|
1020
|
+
};
|
1021
|
+
if (limit !== undefined) {
|
1022
|
+
request['n'] = limit; // max 100
|
1023
|
+
}
|
1024
|
+
const response = await this.v1PublicGetTrades (this.extend (request, params));
|
1025
|
+
//
|
1026
|
+
// {
|
1027
|
+
// "code":0,
|
1028
|
+
// "data":{
|
1029
|
+
// "m":"trades",
|
1030
|
+
// "symbol":"BTC-PERP",
|
1031
|
+
// "data":[
|
1032
|
+
// {"p":"9128.5","q":"0.0030","ts":1590229002385,"bm":false,"seqnum":180143985289898554},
|
1033
|
+
// {"p":"9129","q":"0.0030","ts":1590229002642,"bm":false,"seqnum":180143985289898587},
|
1034
|
+
// {"p":"9129.5","q":"0.0030","ts":1590229021306,"bm":false,"seqnum":180143985289899043}
|
1035
|
+
// ]
|
1036
|
+
// }
|
1037
|
+
// }
|
1038
|
+
//
|
1039
|
+
const records = this.safeValue (response, 'data', []);
|
1040
|
+
const trades = this.safeValue (records, 'data', []);
|
1041
|
+
return this.parseTrades (trades, market, since, limit);
|
1042
|
+
}
|
1043
|
+
|
1044
|
+
parseOrderStatus (status) {
|
1045
|
+
const statuses = {
|
1046
|
+
'PendingNew': 'open',
|
1047
|
+
'New': 'open',
|
1048
|
+
'PartiallyFilled': 'open',
|
1049
|
+
'Filled': 'closed',
|
1050
|
+
'Canceled': 'canceled',
|
1051
|
+
'Rejected': 'rejected',
|
1052
|
+
};
|
1053
|
+
return this.safeString (statuses, status, status);
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
parseOrder (order, market = undefined) {
|
1057
|
+
//
|
1058
|
+
// createOrder
|
1059
|
+
//
|
1060
|
+
// {
|
1061
|
+
// "id": "16e607e2b83a8bXHbAwwoqDo55c166fa",
|
1062
|
+
// "orderId": "16e85b4d9b9a8bXHbAwwoqDoc3d66830",
|
1063
|
+
// "orderType": "Market",
|
1064
|
+
// "symbol": "BTC/USDT",
|
1065
|
+
// "timestamp": 1573576916201
|
1066
|
+
// }
|
1067
|
+
//
|
1068
|
+
// {
|
1069
|
+
// "ac": "FUTURES",
|
1070
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1071
|
+
// "time": 1640819389454,
|
1072
|
+
// "orderId": "a17e0874ecbdU0711043490bbtcpDU5X",
|
1073
|
+
// "seqNum": -1,
|
1074
|
+
// "orderType": "Limit",
|
1075
|
+
// "execInst": "NULL_VAL",
|
1076
|
+
// "side": "Buy",
|
1077
|
+
// "symbol": "BTC-PERP",
|
1078
|
+
// "price": "30000",
|
1079
|
+
// "orderQty": "0.002",
|
1080
|
+
// "stopPrice": "0",
|
1081
|
+
// "stopBy": "ref-px",
|
1082
|
+
// "status": "Ack",
|
1083
|
+
// "lastExecTime": 1640819389454,
|
1084
|
+
// "lastQty": "0",
|
1085
|
+
// "lastPx": "0",
|
1086
|
+
// "avgFilledPx": "0",
|
1087
|
+
// "cumFilledQty": "0",
|
1088
|
+
// "fee": "0",
|
1089
|
+
// "cumFee": "0",
|
1090
|
+
// "feeAsset": "",
|
1091
|
+
// "errorCode": "",
|
1092
|
+
// "posStopLossPrice": "0",
|
1093
|
+
// "posStopLossTrigger": "market",
|
1094
|
+
// "posTakeProfitPrice": "0",
|
1095
|
+
// "posTakeProfitTrigger": "market",
|
1096
|
+
// "liquidityInd": "n"
|
1097
|
+
// }
|
1098
|
+
//
|
1099
|
+
// fetchOrder, fetchOpenOrders, fetchClosedOrders
|
1100
|
+
//
|
1101
|
+
// {
|
1102
|
+
// "symbol": "BTC/USDT",
|
1103
|
+
// "price": "8131.22",
|
1104
|
+
// "orderQty": "0.00082",
|
1105
|
+
// "orderType": "Market",
|
1106
|
+
// "avgPx": "7392.02",
|
1107
|
+
// "cumFee": "0.005152238",
|
1108
|
+
// "cumFilledQty": "0.00082",
|
1109
|
+
// "errorCode": "",
|
1110
|
+
// "feeAsset": "USDT",
|
1111
|
+
// "lastExecTime": 1575953151764,
|
1112
|
+
// "orderId": "a16eee20b6750866943712zWEDdAjt3",
|
1113
|
+
// "seqNum": 2623469,
|
1114
|
+
// "side": "Buy",
|
1115
|
+
// "status": "Filled",
|
1116
|
+
// "stopPrice": "",
|
1117
|
+
// "execInst": "NULL_VAL"
|
1118
|
+
// }
|
1119
|
+
//
|
1120
|
+
// {
|
1121
|
+
// "ac": "FUTURES",
|
1122
|
+
// "accountId": "testabcdefg",
|
1123
|
+
// "avgPx": "0",
|
1124
|
+
// "cumFee": "0",
|
1125
|
+
// "cumQty": "0",
|
1126
|
+
// "errorCode": "NULL_VAL",
|
1127
|
+
// "execInst": "NULL_VAL",
|
1128
|
+
// "feeAsset": "USDT",
|
1129
|
+
// "lastExecTime": 1584072844085,
|
1130
|
+
// "orderId": "r170d21956dd5450276356bbtcpKa74",
|
1131
|
+
// "orderQty": "1.1499",
|
1132
|
+
// "orderType": "Limit",
|
1133
|
+
// "price": "4000",
|
1134
|
+
// "sendingTime": 1584072841033,
|
1135
|
+
// "seqNum": 24105338,
|
1136
|
+
// "side": "Buy",
|
1137
|
+
// "status": "Canceled",
|
1138
|
+
// "stopPrice": "",
|
1139
|
+
// "symbol": "BTC-PERP"
|
1140
|
+
// },
|
1141
|
+
//
|
1142
|
+
const status = this.parseOrderStatus (this.safeString (order, 'status'));
|
1143
|
+
const marketId = this.safeString (order, 'symbol');
|
1144
|
+
const symbol = this.safeSymbol (marketId, market, '/');
|
1145
|
+
const timestamp = this.safeInteger2 (order, 'timestamp', 'sendingTime');
|
1146
|
+
const lastTradeTimestamp = this.safeInteger (order, 'lastExecTime');
|
1147
|
+
const price = this.safeString (order, 'price');
|
1148
|
+
const amount = this.safeString (order, 'orderQty');
|
1149
|
+
const average = this.safeString (order, 'avgPx');
|
1150
|
+
const filled = this.safeString2 (order, 'cumFilledQty', 'cumQty');
|
1151
|
+
const id = this.safeString (order, 'orderId');
|
1152
|
+
let clientOrderId = this.safeString (order, 'id');
|
1153
|
+
if (clientOrderId !== undefined) {
|
1154
|
+
if (clientOrderId.length < 1) {
|
1155
|
+
clientOrderId = undefined;
|
1156
|
+
}
|
1157
|
+
}
|
1158
|
+
const type = this.safeStringLower (order, 'orderType');
|
1159
|
+
const side = this.safeStringLower (order, 'side');
|
1160
|
+
const feeCost = this.safeNumber (order, 'cumFee');
|
1161
|
+
let fee = undefined;
|
1162
|
+
if (feeCost !== undefined) {
|
1163
|
+
const feeCurrencyId = this.safeString (order, 'feeAsset');
|
1164
|
+
const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
|
1165
|
+
fee = {
|
1166
|
+
'cost': feeCost,
|
1167
|
+
'currency': feeCurrencyCode,
|
1168
|
+
};
|
1169
|
+
}
|
1170
|
+
const stopPrice = this.safeNumber (order, 'stopPrice');
|
1171
|
+
return this.safeOrder ({
|
1172
|
+
'info': order,
|
1173
|
+
'id': id,
|
1174
|
+
'clientOrderId': clientOrderId,
|
1175
|
+
'timestamp': timestamp,
|
1176
|
+
'datetime': this.iso8601 (timestamp),
|
1177
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
1178
|
+
'symbol': symbol,
|
1179
|
+
'type': type,
|
1180
|
+
'timeInForce': undefined,
|
1181
|
+
'postOnly': undefined,
|
1182
|
+
'side': side,
|
1183
|
+
'price': price,
|
1184
|
+
'stopPrice': stopPrice,
|
1185
|
+
'amount': amount,
|
1186
|
+
'cost': undefined,
|
1187
|
+
'average': average,
|
1188
|
+
'filled': filled,
|
1189
|
+
'remaining': undefined,
|
1190
|
+
'status': status,
|
1191
|
+
'fee': fee,
|
1192
|
+
'trades': undefined,
|
1193
|
+
}, market);
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
async fetchTradingFees (params = {}) {
|
1197
|
+
await this.loadMarkets ();
|
1198
|
+
await this.loadAccounts ();
|
1199
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1200
|
+
const accountGroup = this.safeString (account, 'id');
|
1201
|
+
const request = {
|
1202
|
+
'account-group': accountGroup,
|
1203
|
+
};
|
1204
|
+
const response = await this.v1PrivateAccountGroupGetSpotFee (this.extend (request, params));
|
1205
|
+
//
|
1206
|
+
// {
|
1207
|
+
// code: '0',
|
1208
|
+
// data: {
|
1209
|
+
// domain: 'spot',
|
1210
|
+
// userUID: 'U1479576458',
|
1211
|
+
// vipLevel: '0',
|
1212
|
+
// fees: [
|
1213
|
+
// { symbol: 'HT/USDT', fee: { taker: '0.001', maker: '0.001' } },
|
1214
|
+
// { symbol: 'LAMB/BTC', fee: { taker: '0.002', maker: '0.002' } },
|
1215
|
+
// { symbol: 'STOS/USDT', fee: { taker: '0.002', maker: '0.002' } },
|
1216
|
+
// ...
|
1217
|
+
// ]
|
1218
|
+
// }
|
1219
|
+
// }
|
1220
|
+
//
|
1221
|
+
const data = this.safeValue (response, 'data', {});
|
1222
|
+
const fees = this.safeValue (data, 'fees', []);
|
1223
|
+
const result = {};
|
1224
|
+
for (let i = 0; i < fees.length; i++) {
|
1225
|
+
const fee = fees[i];
|
1226
|
+
const marketId = this.safeString (fee, 'symbol');
|
1227
|
+
const symbol = this.safeSymbol (marketId, undefined, '/');
|
1228
|
+
const takerMaker = this.safeValue (fee, 'fee', {});
|
1229
|
+
result[symbol] = {
|
1230
|
+
'info': fee,
|
1231
|
+
'symbol': symbol,
|
1232
|
+
'maker': this.safeNumber (takerMaker, 'maker'),
|
1233
|
+
'taker': this.safeNumber (takerMaker, 'taker'),
|
1234
|
+
};
|
1235
|
+
}
|
1236
|
+
return result;
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
1240
|
+
await this.loadMarkets ();
|
1241
|
+
await this.loadAccounts ();
|
1242
|
+
const market = this.market (symbol);
|
1243
|
+
let marketType = undefined;
|
1244
|
+
[ marketType, params ] = this.handleMarketTypeAndParams ('createOrder', market, params);
|
1245
|
+
const options = this.safeValue (this.options, 'createOrder', {});
|
1246
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
1247
|
+
const accountCategory = this.safeString (accountsByType, marketType, 'cash');
|
1248
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1249
|
+
const accountGroup = this.safeValue (account, 'id');
|
1250
|
+
const clientOrderId = this.safeString2 (params, 'clientOrderId', 'id');
|
1251
|
+
const reduceOnly = this.safeValue (params, 'execInst');
|
1252
|
+
if (reduceOnly !== undefined) {
|
1253
|
+
if ((marketType !== 'swap')) {
|
1254
|
+
throw new InvalidOrder (this.id + ' createOrder() does not support reduceOnly for ' + marketType + ' orders, reduceOnly orders are supported for perpetuals only');
|
1255
|
+
}
|
1256
|
+
}
|
1257
|
+
const request = {
|
1258
|
+
'account-group': accountGroup,
|
1259
|
+
'account-category': accountCategory,
|
1260
|
+
'symbol': market['id'],
|
1261
|
+
'time': this.milliseconds (),
|
1262
|
+
'orderQty': this.amountToPrecision (symbol, amount),
|
1263
|
+
'orderType': type, // "limit", "market", "stop_market", "stop_limit"
|
1264
|
+
'side': side, // "buy" or "sell"
|
1265
|
+
// 'orderPrice': this.priceToPrecision (symbol, price),
|
1266
|
+
// 'stopPrice': this.priceToPrecision (symbol, stopPrice), // required for stop orders
|
1267
|
+
// 'postOnly': 'false', // 'false', 'true'
|
1268
|
+
// 'timeInForce': 'GTC', // GTC, IOC, FOK
|
1269
|
+
// 'respInst': 'ACK', // ACK, 'ACCEPT, DONE
|
1270
|
+
// 'posStopLossPrice': position stop loss price ( v2 swap orders only)
|
1271
|
+
// 'posTakeProfitPrice': position take profit price (v2 swap orders only)
|
1272
|
+
};
|
1273
|
+
if (clientOrderId !== undefined) {
|
1274
|
+
request['id'] = clientOrderId;
|
1275
|
+
params = this.omit (params, [ 'clientOrderId', 'id' ]);
|
1276
|
+
}
|
1277
|
+
if ((type === 'limit') || (type === 'stop_limit')) {
|
1278
|
+
request['orderPrice'] = this.priceToPrecision (symbol, price);
|
1279
|
+
}
|
1280
|
+
if ((type === 'stop_limit') || (type === 'stop_market')) {
|
1281
|
+
const stopPrice = this.safeNumber (params, 'stopPrice');
|
1282
|
+
if (stopPrice === undefined) {
|
1283
|
+
throw new InvalidOrder (this.id + ' createOrder() requires a stopPrice parameter for ' + type + ' orders');
|
1284
|
+
} else {
|
1285
|
+
request['stopPrice'] = this.priceToPrecision (symbol, stopPrice);
|
1286
|
+
params = this.omit (params, 'stopPrice');
|
1287
|
+
}
|
1288
|
+
}
|
1289
|
+
const timeInForce = this.safeString (params, 'timeInForce');
|
1290
|
+
const postOnly = this.safeValue (params, 'postOnly', false);
|
1291
|
+
if ((timeInForce === 'PO') || (postOnly)) {
|
1292
|
+
request['postOnly'] = true;
|
1293
|
+
params = this.omit (params, [ 'postOnly', 'timeInForce' ]);
|
1294
|
+
}
|
1295
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountCategoryPostOrder');
|
1296
|
+
const method = this.getSupportedMapping (marketType, {
|
1297
|
+
'spot': defaultMethod,
|
1298
|
+
'margin': defaultMethod,
|
1299
|
+
'swap': 'v2PrivateAccountGroupPostFuturesOrder',
|
1300
|
+
});
|
1301
|
+
if (method === 'v1PrivateAccountCategoryPostOrder') {
|
1302
|
+
if (accountCategory !== undefined) {
|
1303
|
+
request['category'] = accountCategory;
|
1304
|
+
}
|
1305
|
+
} else {
|
1306
|
+
request['account-category'] = accountCategory;
|
1307
|
+
}
|
1308
|
+
const response = await this[method] (this.extend (request, params));
|
1309
|
+
//
|
1310
|
+
// AccountCategoryPostOrder
|
1311
|
+
//
|
1312
|
+
// {
|
1313
|
+
// "code": 0,
|
1314
|
+
// "data": {
|
1315
|
+
// "ac": "MARGIN",
|
1316
|
+
// "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
|
1317
|
+
// "action": "place-order",
|
1318
|
+
// "info": {
|
1319
|
+
// "id": "16e607e2b83a8bXHbAwwoqDo55c166fa",
|
1320
|
+
// "orderId": "16e85b4d9b9a8bXHbAwwoqDoc3d66830",
|
1321
|
+
// "orderType": "Market",
|
1322
|
+
// "symbol": "BTC/USDT",
|
1323
|
+
// "timestamp": 1573576916201
|
1324
|
+
// },
|
1325
|
+
// "status": "Ack"
|
1326
|
+
// }
|
1327
|
+
// }
|
1328
|
+
//
|
1329
|
+
// AccountGroupPostFuturesOrder
|
1330
|
+
//
|
1331
|
+
// {
|
1332
|
+
// "code": 0,
|
1333
|
+
// "data": {
|
1334
|
+
// "meta": {
|
1335
|
+
// "id": "",
|
1336
|
+
// "action": "place-order",
|
1337
|
+
// "respInst": "ACK"
|
1338
|
+
// },
|
1339
|
+
// "order": {
|
1340
|
+
// "ac": "FUTURES",
|
1341
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1342
|
+
// "time": 1640819389454,
|
1343
|
+
// "orderId": "a17e0874ecbdU0711043490bbtcpDU5X",
|
1344
|
+
// "seqNum": -1,
|
1345
|
+
// "orderType": "Limit",
|
1346
|
+
// "execInst": "NULL_VAL",
|
1347
|
+
// "side": "Buy",
|
1348
|
+
// "symbol": "BTC-PERP",
|
1349
|
+
// "price": "30000",
|
1350
|
+
// "orderQty": "0.002",
|
1351
|
+
// "stopPrice": "0",
|
1352
|
+
// "stopBy": "ref-px",
|
1353
|
+
// "status": "Ack",
|
1354
|
+
// "lastExecTime": 1640819389454,
|
1355
|
+
// "lastQty": "0",
|
1356
|
+
// "lastPx": "0",
|
1357
|
+
// "avgFilledPx": "0",
|
1358
|
+
// "cumFilledQty": "0",
|
1359
|
+
// "fee": "0",
|
1360
|
+
// "cumFee": "0",
|
1361
|
+
// "feeAsset": "",
|
1362
|
+
// "errorCode": "",
|
1363
|
+
// "posStopLossPrice": "0",
|
1364
|
+
// "posStopLossTrigger": "market",
|
1365
|
+
// "posTakeProfitPrice": "0",
|
1366
|
+
// "posTakeProfitTrigger": "market",
|
1367
|
+
// "liquidityInd": "n"
|
1368
|
+
// }
|
1369
|
+
// }
|
1370
|
+
// }
|
1371
|
+
//
|
1372
|
+
const data = this.safeValue (response, 'data', {});
|
1373
|
+
const order = this.safeValue2 (data, 'order', 'info', {});
|
1374
|
+
return this.parseOrder (order, market);
|
1375
|
+
}
|
1376
|
+
|
1377
|
+
async createReduceOnlyOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
1378
|
+
const request = {
|
1379
|
+
'execInst': 'reduceOnly',
|
1380
|
+
};
|
1381
|
+
return await this.createOrder (symbol, type, side, amount, price, this.extend (request, params));
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
async fetchOrder (id, symbol = undefined, params = {}) {
|
1385
|
+
await this.loadMarkets ();
|
1386
|
+
await this.loadAccounts ();
|
1387
|
+
let market = undefined;
|
1388
|
+
if (symbol !== undefined) {
|
1389
|
+
market = this.market (symbol);
|
1390
|
+
}
|
1391
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('fetchOrder', market, params);
|
1392
|
+
const options = this.safeValue (this.options, 'fetchOrder', {});
|
1393
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
1394
|
+
const accountCategory = this.safeString (accountsByType, type, 'cash');
|
1395
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1396
|
+
const accountGroup = this.safeValue (account, 'id');
|
1397
|
+
const request = {
|
1398
|
+
'account-group': accountGroup,
|
1399
|
+
'account-category': accountCategory,
|
1400
|
+
'orderId': id,
|
1401
|
+
};
|
1402
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountCategoryGetOrderStatus');
|
1403
|
+
const method = this.getSupportedMapping (type, {
|
1404
|
+
'spot': defaultMethod,
|
1405
|
+
'margin': defaultMethod,
|
1406
|
+
'swap': 'v2PrivateAccountGroupGetFuturesOrderStatus',
|
1407
|
+
});
|
1408
|
+
if (method === 'v1PrivateAccountCategoryGetOrderStatus') {
|
1409
|
+
if (accountCategory !== undefined) {
|
1410
|
+
request['category'] = accountCategory;
|
1411
|
+
}
|
1412
|
+
} else {
|
1413
|
+
request['account-category'] = accountCategory;
|
1414
|
+
}
|
1415
|
+
const response = await this[method] (this.extend (request, query));
|
1416
|
+
//
|
1417
|
+
// AccountCategoryGetOrderStatus
|
1418
|
+
//
|
1419
|
+
// {
|
1420
|
+
// "code": 0,
|
1421
|
+
// "accountCategory": "CASH",
|
1422
|
+
// "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
|
1423
|
+
// "data": [
|
1424
|
+
// {
|
1425
|
+
// "symbol": "BTC/USDT",
|
1426
|
+
// "price": "8131.22",
|
1427
|
+
// "orderQty": "0.00082",
|
1428
|
+
// "orderType": "Market",
|
1429
|
+
// "avgPx": "7392.02",
|
1430
|
+
// "cumFee": "0.005152238",
|
1431
|
+
// "cumFilledQty": "0.00082",
|
1432
|
+
// "errorCode": "",
|
1433
|
+
// "feeAsset": "USDT",
|
1434
|
+
// "lastExecTime": 1575953151764,
|
1435
|
+
// "orderId": "a16eee20b6750866943712zWEDdAjt3",
|
1436
|
+
// "seqNum": 2623469,
|
1437
|
+
// "side": "Buy",
|
1438
|
+
// "status": "Filled",
|
1439
|
+
// "stopPrice": "",
|
1440
|
+
// "execInst": "NULL_VAL"
|
1441
|
+
// }
|
1442
|
+
// ]
|
1443
|
+
// }
|
1444
|
+
//
|
1445
|
+
// AccountGroupGetFuturesOrderStatus
|
1446
|
+
//
|
1447
|
+
// {
|
1448
|
+
// "code": 0,
|
1449
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1450
|
+
// "ac": "FUTURES",
|
1451
|
+
// "data": {
|
1452
|
+
// "ac": "FUTURES",
|
1453
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1454
|
+
// "time": 1640247020217,
|
1455
|
+
// "orderId": "r17de65747aeU0711043490bbtcp0cmt",
|
1456
|
+
// "seqNum": 28796162908,
|
1457
|
+
// "orderType": "Limit",
|
1458
|
+
// "execInst": "NULL_VAL",
|
1459
|
+
// "side": "Buy",
|
1460
|
+
// "symbol": "BTC-PERP",
|
1461
|
+
// "price": "30000",
|
1462
|
+
// "orderQty": "0.0021",
|
1463
|
+
// "stopPrice": "0",
|
1464
|
+
// "stopBy": "market",
|
1465
|
+
// "status": "New",
|
1466
|
+
// "lastExecTime": 1640247020232,
|
1467
|
+
// "lastQty": "0",
|
1468
|
+
// "lastPx": "0",
|
1469
|
+
// "avgFilledPx": "0",
|
1470
|
+
// "cumFilledQty": "0",
|
1471
|
+
// "fee": "0",
|
1472
|
+
// "cumFee": "0",
|
1473
|
+
// "feeAsset": "USDT",
|
1474
|
+
// "errorCode": "",
|
1475
|
+
// "posStopLossPrice": "0",
|
1476
|
+
// "posStopLossTrigger": "market",
|
1477
|
+
// "posTakeProfitPrice": "0",
|
1478
|
+
// "posTakeProfitTrigger": "market",
|
1479
|
+
// "liquidityInd": "n"
|
1480
|
+
// }
|
1481
|
+
// }
|
1482
|
+
//
|
1483
|
+
const data = this.safeValue (response, 'data', {});
|
1484
|
+
return this.parseOrder (data, market);
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
1488
|
+
await this.loadMarkets ();
|
1489
|
+
await this.loadAccounts ();
|
1490
|
+
let market = undefined;
|
1491
|
+
if (symbol !== undefined) {
|
1492
|
+
market = this.market (symbol);
|
1493
|
+
symbol = market['symbol'];
|
1494
|
+
}
|
1495
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1496
|
+
const accountGroup = this.safeValue (account, 'id');
|
1497
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('fetchOpenOrders', market, params);
|
1498
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
1499
|
+
const accountCategory = this.safeString (accountsByType, type, 'cash');
|
1500
|
+
const request = {
|
1501
|
+
'account-group': accountGroup,
|
1502
|
+
'account-category': accountCategory,
|
1503
|
+
};
|
1504
|
+
const options = this.safeValue (this.options, 'fetchOpenOrders', {});
|
1505
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountCategoryGetOrderOpen');
|
1506
|
+
const method = this.getSupportedMapping (type, {
|
1507
|
+
'spot': defaultMethod,
|
1508
|
+
'margin': defaultMethod,
|
1509
|
+
'swap': 'v2PrivateAccountGroupGetFuturesOrderOpen',
|
1510
|
+
});
|
1511
|
+
if (method === 'v1PrivateAccountCategoryGetOrderOpen') {
|
1512
|
+
if (accountCategory !== undefined) {
|
1513
|
+
request['category'] = accountCategory;
|
1514
|
+
}
|
1515
|
+
} else {
|
1516
|
+
request['account-category'] = accountCategory;
|
1517
|
+
}
|
1518
|
+
const response = await this[method] (this.extend (request, query));
|
1519
|
+
//
|
1520
|
+
// AccountCategoryGetOrderOpen
|
1521
|
+
//
|
1522
|
+
// {
|
1523
|
+
// "ac": "CASH",
|
1524
|
+
// "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
|
1525
|
+
// "code": 0,
|
1526
|
+
// "data": [
|
1527
|
+
// {
|
1528
|
+
// "avgPx": "0", // Average filled price of the order
|
1529
|
+
// "cumFee": "0", // cumulative fee paid for this order
|
1530
|
+
// "cumFilledQty": "0", // cumulative filled quantity
|
1531
|
+
// "errorCode": "", // error code; could be empty
|
1532
|
+
// "feeAsset": "USDT", // fee asset
|
1533
|
+
// "lastExecTime": 1576019723550, // The last execution time of the order
|
1534
|
+
// "orderId": "s16ef21882ea0866943712034f36d83", // server provided orderId
|
1535
|
+
// "orderQty": "0.0083", // order quantity
|
1536
|
+
// "orderType": "Limit", // order type
|
1537
|
+
// "price": "7105", // order price
|
1538
|
+
// "seqNum": 8193258, // sequence number
|
1539
|
+
// "side": "Buy", // order side
|
1540
|
+
// "status": "New", // order status on matching engine
|
1541
|
+
// "stopPrice": "", // only available for stop market and stop limit orders; otherwise empty
|
1542
|
+
// "symbol": "BTC/USDT",
|
1543
|
+
// "execInst": "NULL_VAL" // execution instruction
|
1544
|
+
// },
|
1545
|
+
// ]
|
1546
|
+
// }
|
1547
|
+
//
|
1548
|
+
// AccountGroupGetFuturesOrderOpen
|
1549
|
+
//
|
1550
|
+
// {
|
1551
|
+
// "code": 0,
|
1552
|
+
// "data": [
|
1553
|
+
// {
|
1554
|
+
// "ac": "FUTURES",
|
1555
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1556
|
+
// "time": 1640247020217,
|
1557
|
+
// "orderId": "r17de65747aeU0711043490bbtcp0cmt",
|
1558
|
+
// "seqNum": 28796162908,
|
1559
|
+
// "orderType": "Limit",
|
1560
|
+
// "execInst": "NULL_VAL",
|
1561
|
+
// "side": "Buy",
|
1562
|
+
// "symbol": "BTC-PERP",
|
1563
|
+
// "price": "30000",
|
1564
|
+
// "orderQty": "0.0021",
|
1565
|
+
// "stopPrice": "0",
|
1566
|
+
// "stopBy": "market",
|
1567
|
+
// "status": "New",
|
1568
|
+
// "lastExecTime": 1640247020232,
|
1569
|
+
// "lastQty": "0",
|
1570
|
+
// "lastPx": "0",
|
1571
|
+
// "avgFilledPx": "0",
|
1572
|
+
// "cumFilledQty": "0",
|
1573
|
+
// "fee": "0",
|
1574
|
+
// "cumFee": "0",
|
1575
|
+
// "feeAsset": "USDT",
|
1576
|
+
// "errorCode": "",
|
1577
|
+
// "posStopLossPrice": "0",
|
1578
|
+
// "posStopLossTrigger": "market",
|
1579
|
+
// "posTakeProfitPrice": "0",
|
1580
|
+
// "posTakeProfitTrigger": "market",
|
1581
|
+
// "liquidityInd": "n"
|
1582
|
+
// }
|
1583
|
+
// ]
|
1584
|
+
// }
|
1585
|
+
//
|
1586
|
+
const data = this.safeValue (response, 'data', []);
|
1587
|
+
if (accountCategory === 'futures') {
|
1588
|
+
return this.parseOrders (data, market, since, limit);
|
1589
|
+
}
|
1590
|
+
// a workaround for https://github.com/ccxt/ccxt/issues/7187
|
1591
|
+
const orders = [];
|
1592
|
+
for (let i = 0; i < data.length; i++) {
|
1593
|
+
const order = this.parseOrder (data[i], market);
|
1594
|
+
orders.push (order);
|
1595
|
+
}
|
1596
|
+
return this.filterBySymbolSinceLimit (orders, symbol, since, limit);
|
1597
|
+
}
|
1598
|
+
|
1599
|
+
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
1600
|
+
await this.loadMarkets ();
|
1601
|
+
await this.loadAccounts ();
|
1602
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1603
|
+
const accountGroup = this.safeValue (account, 'id');
|
1604
|
+
const request = {
|
1605
|
+
'account-group': accountGroup,
|
1606
|
+
// 'category': accountCategory,
|
1607
|
+
// 'symbol': market['id'],
|
1608
|
+
// 'orderType': 'market', // optional, string
|
1609
|
+
// 'side': 'buy', // or 'sell', optional, case insensitive.
|
1610
|
+
// 'status': 'Filled', // "Filled", "Canceled", or "Rejected"
|
1611
|
+
// 'startTime': exchange.milliseconds (),
|
1612
|
+
// 'endTime': exchange.milliseconds (),
|
1613
|
+
// 'page': 1,
|
1614
|
+
// 'pageSize': 100,
|
1615
|
+
};
|
1616
|
+
let market = undefined;
|
1617
|
+
if (symbol !== undefined) {
|
1618
|
+
market = this.market (symbol);
|
1619
|
+
request['symbol'] = market['id'];
|
1620
|
+
}
|
1621
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('fetchCLosedOrders', market, params);
|
1622
|
+
const options = this.safeValue (this.options, 'fetchClosedOrders', {});
|
1623
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountGroupGetOrderHist');
|
1624
|
+
const method = this.getSupportedMapping (type, {
|
1625
|
+
'spot': defaultMethod,
|
1626
|
+
'margin': defaultMethod,
|
1627
|
+
'swap': 'v2PrivateAccountGroupGetFuturesOrderHistCurrent',
|
1628
|
+
});
|
1629
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
1630
|
+
const accountCategory = this.safeString (accountsByType, type, 'cash');
|
1631
|
+
if (method === 'v1PrivateAccountGroupGetOrderHist') {
|
1632
|
+
if (accountCategory !== undefined) {
|
1633
|
+
request['category'] = accountCategory;
|
1634
|
+
}
|
1635
|
+
} else {
|
1636
|
+
request['account-category'] = accountCategory;
|
1637
|
+
}
|
1638
|
+
if (since !== undefined) {
|
1639
|
+
request['startTime'] = since;
|
1640
|
+
}
|
1641
|
+
if (limit !== undefined) {
|
1642
|
+
request['pageSize'] = limit;
|
1643
|
+
}
|
1644
|
+
const response = await this[method] (this.extend (request, query));
|
1645
|
+
//
|
1646
|
+
// accountCategoryGetOrderHistCurrent
|
1647
|
+
//
|
1648
|
+
// {
|
1649
|
+
// "code":0,
|
1650
|
+
// "accountId":"cshrHKLZCjlZ2ejqkmvIHHtPmLYqdnda",
|
1651
|
+
// "ac":"CASH",
|
1652
|
+
// "data":[
|
1653
|
+
// {
|
1654
|
+
// "seqNum":15561826728,
|
1655
|
+
// "orderId":"a17294d305c0U6491137460bethu7kw9",
|
1656
|
+
// "symbol":"ETH/USDT",
|
1657
|
+
// "orderType":"Limit",
|
1658
|
+
// "lastExecTime":1591635618200,
|
1659
|
+
// "price":"200",
|
1660
|
+
// "orderQty":"0.1",
|
1661
|
+
// "side":"Buy",
|
1662
|
+
// "status":"Canceled",
|
1663
|
+
// "avgPx":"0",
|
1664
|
+
// "cumFilledQty":"0",
|
1665
|
+
// "stopPrice":"",
|
1666
|
+
// "errorCode":"",
|
1667
|
+
// "cumFee":"0",
|
1668
|
+
// "feeAsset":"USDT",
|
1669
|
+
// "execInst":"NULL_VAL"
|
1670
|
+
// }
|
1671
|
+
// ]
|
1672
|
+
// }
|
1673
|
+
//
|
1674
|
+
// accountGroupGetOrderHist
|
1675
|
+
//
|
1676
|
+
// {
|
1677
|
+
// "code": 0,
|
1678
|
+
// "data": {
|
1679
|
+
// "data": [
|
1680
|
+
// {
|
1681
|
+
// "ac": "FUTURES",
|
1682
|
+
// "accountId": "testabcdefg",
|
1683
|
+
// "avgPx": "0",
|
1684
|
+
// "cumFee": "0",
|
1685
|
+
// "cumQty": "0",
|
1686
|
+
// "errorCode": "NULL_VAL",
|
1687
|
+
// "execInst": "NULL_VAL",
|
1688
|
+
// "feeAsset": "USDT",
|
1689
|
+
// "lastExecTime": 1584072844085,
|
1690
|
+
// "orderId": "r170d21956dd5450276356bbtcpKa74",
|
1691
|
+
// "orderQty": "1.1499",
|
1692
|
+
// "orderType": "Limit",
|
1693
|
+
// "price": "4000",
|
1694
|
+
// "sendingTime": 1584072841033,
|
1695
|
+
// "seqNum": 24105338,
|
1696
|
+
// "side": "Buy",
|
1697
|
+
// "status": "Canceled",
|
1698
|
+
// "stopPrice": "",
|
1699
|
+
// "symbol": "BTC-PERP"
|
1700
|
+
// },
|
1701
|
+
// ],
|
1702
|
+
// "hasNext": False,
|
1703
|
+
// "limit": 500,
|
1704
|
+
// "page": 1,
|
1705
|
+
// "pageSize": 20
|
1706
|
+
// }
|
1707
|
+
// }
|
1708
|
+
//
|
1709
|
+
// accountGroupGetFuturesOrderHistCurrent
|
1710
|
+
//
|
1711
|
+
// {
|
1712
|
+
// "code": 0,
|
1713
|
+
// "data": [
|
1714
|
+
// {
|
1715
|
+
// "ac": "FUTURES",
|
1716
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1717
|
+
// "time": 1640245777002,
|
1718
|
+
// "orderId": "r17de6444fa6U0711043490bbtcpJ2lI",
|
1719
|
+
// "seqNum": 28796124902,
|
1720
|
+
// "orderType": "Limit",
|
1721
|
+
// "execInst": "NULL_VAL",
|
1722
|
+
// "side": "Buy",
|
1723
|
+
// "symbol": "BTC-PERP",
|
1724
|
+
// "price": "30000",
|
1725
|
+
// "orderQty": "0.0021",
|
1726
|
+
// "stopPrice": "0",
|
1727
|
+
// "stopBy": "market",
|
1728
|
+
// "status": "Canceled",
|
1729
|
+
// "lastExecTime": 1640246574886,
|
1730
|
+
// "lastQty": "0",
|
1731
|
+
// "lastPx": "0",
|
1732
|
+
// "avgFilledPx": "0",
|
1733
|
+
// "cumFilledQty": "0",
|
1734
|
+
// "fee": "0",
|
1735
|
+
// "cumFee": "0",
|
1736
|
+
// "feeAsset": "USDT",
|
1737
|
+
// "errorCode": "",
|
1738
|
+
// "posStopLossPrice": "0",
|
1739
|
+
// "posStopLossTrigger": "market",
|
1740
|
+
// "posTakeProfitPrice": "0",
|
1741
|
+
// "posTakeProfitTrigger": "market",
|
1742
|
+
// "liquidityInd": "n"
|
1743
|
+
// }
|
1744
|
+
// ]
|
1745
|
+
// }
|
1746
|
+
//
|
1747
|
+
let data = this.safeValue (response, 'data');
|
1748
|
+
const isArray = Array.isArray (data);
|
1749
|
+
if (!isArray) {
|
1750
|
+
data = this.safeValue (data, 'data', []);
|
1751
|
+
}
|
1752
|
+
return this.parseOrders (data, market, since, limit);
|
1753
|
+
}
|
1754
|
+
|
1755
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
1756
|
+
if (symbol === undefined) {
|
1757
|
+
throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
|
1758
|
+
}
|
1759
|
+
await this.loadMarkets ();
|
1760
|
+
await this.loadAccounts ();
|
1761
|
+
const market = this.market (symbol);
|
1762
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('cancelOrder', market, params);
|
1763
|
+
const options = this.safeValue (this.options, 'cancelOrder', {});
|
1764
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
1765
|
+
const accountCategory = this.safeString (accountsByType, type, 'cash');
|
1766
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1767
|
+
const accountGroup = this.safeValue (account, 'id');
|
1768
|
+
const request = {
|
1769
|
+
'account-group': accountGroup,
|
1770
|
+
'account-category': accountCategory,
|
1771
|
+
'symbol': market['id'],
|
1772
|
+
'time': this.milliseconds (),
|
1773
|
+
'id': 'foobar',
|
1774
|
+
};
|
1775
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountCategoryDeleteOrder');
|
1776
|
+
const method = this.getSupportedMapping (type, {
|
1777
|
+
'spot': defaultMethod,
|
1778
|
+
'margin': defaultMethod,
|
1779
|
+
'swap': 'v2PrivateAccountGroupDeleteFuturesOrder',
|
1780
|
+
});
|
1781
|
+
if (method === 'v1PrivateAccountCategoryDeleteOrder') {
|
1782
|
+
if (accountCategory !== undefined) {
|
1783
|
+
request['category'] = accountCategory;
|
1784
|
+
}
|
1785
|
+
} else {
|
1786
|
+
request['account-category'] = accountCategory;
|
1787
|
+
}
|
1788
|
+
const clientOrderId = this.safeString2 (params, 'clientOrderId', 'id');
|
1789
|
+
if (clientOrderId === undefined) {
|
1790
|
+
request['orderId'] = id;
|
1791
|
+
} else {
|
1792
|
+
request['id'] = clientOrderId;
|
1793
|
+
params = this.omit (params, [ 'clientOrderId', 'id' ]);
|
1794
|
+
}
|
1795
|
+
const response = await this[method] (this.extend (request, query));
|
1796
|
+
//
|
1797
|
+
// AccountCategoryDeleteOrder
|
1798
|
+
//
|
1799
|
+
// {
|
1800
|
+
// "code": 0,
|
1801
|
+
// "data": {
|
1802
|
+
// "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
|
1803
|
+
// "ac": "CASH",
|
1804
|
+
// "action": "cancel-order",
|
1805
|
+
// "status": "Ack",
|
1806
|
+
// "info": {
|
1807
|
+
// "id": "wv8QGquoeamhssvQBeHOHGQCGlcBjj23",
|
1808
|
+
// "orderId": "16e6198afb4s8bXHbAwwoqDo2ebc19dc",
|
1809
|
+
// "orderType": "", // could be empty
|
1810
|
+
// "symbol": "ETH/USDT",
|
1811
|
+
// "timestamp": 1573594877822
|
1812
|
+
// }
|
1813
|
+
// }
|
1814
|
+
// }
|
1815
|
+
//
|
1816
|
+
// AccountGroupDeleteFuturesOrder
|
1817
|
+
//
|
1818
|
+
// {
|
1819
|
+
// "code": 0,
|
1820
|
+
// "data": {
|
1821
|
+
// "meta": {
|
1822
|
+
// "id": "foobar",
|
1823
|
+
// "action": "cancel-order",
|
1824
|
+
// "respInst": "ACK"
|
1825
|
+
// },
|
1826
|
+
// "order": {
|
1827
|
+
// "ac": "FUTURES",
|
1828
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1829
|
+
// "time": 1640244480476,
|
1830
|
+
// "orderId": "r17de63086f4U0711043490bbtcpPUF4",
|
1831
|
+
// "seqNum": 28795959269,
|
1832
|
+
// "orderType": "Limit",
|
1833
|
+
// "execInst": "NULL_VAL",
|
1834
|
+
// "side": "Buy",
|
1835
|
+
// "symbol": "BTC-PERP",
|
1836
|
+
// "price": "30000",
|
1837
|
+
// "orderQty": "0.0021",
|
1838
|
+
// "stopPrice": "0",
|
1839
|
+
// "stopBy": "market",
|
1840
|
+
// "status": "New",
|
1841
|
+
// "lastExecTime": 1640244480491,
|
1842
|
+
// "lastQty": "0",
|
1843
|
+
// "lastPx": "0",
|
1844
|
+
// "avgFilledPx": "0",
|
1845
|
+
// "cumFilledQty": "0",
|
1846
|
+
// "fee": "0",
|
1847
|
+
// "cumFee": "0",
|
1848
|
+
// "feeAsset": "BTCPC",
|
1849
|
+
// "errorCode": "",
|
1850
|
+
// "posStopLossPrice": "0",
|
1851
|
+
// "posStopLossTrigger": "market",
|
1852
|
+
// "posTakeProfitPrice": "0",
|
1853
|
+
// "posTakeProfitTrigger": "market",
|
1854
|
+
// "liquidityInd": "n"
|
1855
|
+
// }
|
1856
|
+
// }
|
1857
|
+
// }
|
1858
|
+
//
|
1859
|
+
const data = this.safeValue (response, 'data', {});
|
1860
|
+
const order = this.safeValue2 (data, 'order', 'info', {});
|
1861
|
+
return this.parseOrder (order, market);
|
1862
|
+
}
|
1863
|
+
|
1864
|
+
async cancelAllOrders (symbol = undefined, params = {}) {
|
1865
|
+
await this.loadMarkets ();
|
1866
|
+
await this.loadAccounts ();
|
1867
|
+
let market = undefined;
|
1868
|
+
if (symbol !== undefined) {
|
1869
|
+
market = this.market (symbol);
|
1870
|
+
}
|
1871
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('cancelAllOrders', market, params);
|
1872
|
+
const options = this.safeValue (this.options, 'cancelAllOrders', {});
|
1873
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
1874
|
+
const accountCategory = this.safeString (accountsByType, type, 'cash');
|
1875
|
+
const account = this.safeValue (this.accounts, 0, {});
|
1876
|
+
const accountGroup = this.safeValue (account, 'id');
|
1877
|
+
const request = {
|
1878
|
+
'account-group': accountGroup,
|
1879
|
+
'account-category': accountCategory,
|
1880
|
+
'time': this.milliseconds (),
|
1881
|
+
};
|
1882
|
+
if (symbol !== undefined) {
|
1883
|
+
request['symbol'] = market['id'];
|
1884
|
+
}
|
1885
|
+
const defaultMethod = this.safeString (options, 'method', 'v1PrivateAccountCategoryDeleteOrderAll');
|
1886
|
+
const method = this.getSupportedMapping (type, {
|
1887
|
+
'spot': defaultMethod,
|
1888
|
+
'margin': defaultMethod,
|
1889
|
+
'swap': 'v2PrivateAccountGroupDeleteFuturesOrderAll',
|
1890
|
+
});
|
1891
|
+
if (method === 'v1PrivateAccountCategoryDeleteOrderAll') {
|
1892
|
+
if (accountCategory !== undefined) {
|
1893
|
+
request['category'] = accountCategory;
|
1894
|
+
}
|
1895
|
+
} else {
|
1896
|
+
request['account-category'] = accountCategory;
|
1897
|
+
}
|
1898
|
+
const response = await this[method] (this.extend (request, query));
|
1899
|
+
//
|
1900
|
+
// AccountCategoryDeleteOrderAll
|
1901
|
+
//
|
1902
|
+
// {
|
1903
|
+
// "code": 0,
|
1904
|
+
// "data": {
|
1905
|
+
// "ac": "CASH",
|
1906
|
+
// "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
|
1907
|
+
// "action": "cancel-all",
|
1908
|
+
// "info": {
|
1909
|
+
// "id": "2bmYvi7lyTrneMzpcJcf2D7Pe9V1P9wy",
|
1910
|
+
// "orderId": "",
|
1911
|
+
// "orderType": "NULL_VAL",
|
1912
|
+
// "symbol": "",
|
1913
|
+
// "timestamp": 1574118495462
|
1914
|
+
// },
|
1915
|
+
// "status": "Ack"
|
1916
|
+
// }
|
1917
|
+
// }
|
1918
|
+
//
|
1919
|
+
// AccountGroupDeleteFuturesOrderAll
|
1920
|
+
//
|
1921
|
+
// {
|
1922
|
+
// "code": 0,
|
1923
|
+
// "data": {
|
1924
|
+
// "ac": "FUTURES",
|
1925
|
+
// "accountId": "fut2ODPhGiY71Pl4vtXnOZ00ssgD7QGn",
|
1926
|
+
// "action": "cancel-all",
|
1927
|
+
// "info": {
|
1928
|
+
// "symbol":"BTC-PERP"
|
1929
|
+
// }
|
1930
|
+
// }
|
1931
|
+
// }
|
1932
|
+
//
|
1933
|
+
return response;
|
1934
|
+
}
|
1935
|
+
|
1936
|
+
parseDepositAddress (depositAddress, currency = undefined) {
|
1937
|
+
//
|
1938
|
+
// {
|
1939
|
+
// address: "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
|
1940
|
+
// destTag: "",
|
1941
|
+
// tagType: "",
|
1942
|
+
// tagId: "",
|
1943
|
+
// chainName: "ERC20",
|
1944
|
+
// numConfirmations: 20,
|
1945
|
+
// withdrawalFee: 1,
|
1946
|
+
// nativeScale: 4,
|
1947
|
+
// tips: []
|
1948
|
+
// }
|
1949
|
+
//
|
1950
|
+
const address = this.safeString (depositAddress, 'address');
|
1951
|
+
const tagId = this.safeString (depositAddress, 'tagId');
|
1952
|
+
const tag = this.safeString (depositAddress, tagId);
|
1953
|
+
this.checkAddress (address);
|
1954
|
+
const code = (currency === undefined) ? undefined : currency['code'];
|
1955
|
+
const chainName = this.safeString (depositAddress, 'chainName');
|
1956
|
+
const network = this.safeNetwork (chainName);
|
1957
|
+
return {
|
1958
|
+
'currency': code,
|
1959
|
+
'address': address,
|
1960
|
+
'tag': tag,
|
1961
|
+
'network': network,
|
1962
|
+
'info': depositAddress,
|
1963
|
+
};
|
1964
|
+
}
|
1965
|
+
|
1966
|
+
safeNetwork (networkId) {
|
1967
|
+
const networksById = {
|
1968
|
+
'TRC20': 'TRC20',
|
1969
|
+
'ERC20': 'ERC20',
|
1970
|
+
'GO20': 'GO20',
|
1971
|
+
'BEP2': 'BEP2',
|
1972
|
+
'BEP20 (BSC)': 'BEP20',
|
1973
|
+
'Bitcoin': 'BTC',
|
1974
|
+
'Bitcoin ABC': 'BCH',
|
1975
|
+
'Litecoin': 'LTC',
|
1976
|
+
'Matic Network': 'MATIC',
|
1977
|
+
'Solana': 'SOL',
|
1978
|
+
'xDai': 'STAKE',
|
1979
|
+
'Akash': 'AKT',
|
1980
|
+
};
|
1981
|
+
return this.safeString (networksById, networkId, networkId);
|
1982
|
+
}
|
1983
|
+
|
1984
|
+
async fetchDepositAddress (code, params = {}) {
|
1985
|
+
await this.loadMarkets ();
|
1986
|
+
const currency = this.currency (code);
|
1987
|
+
const chainName = this.safeString (params, 'chainName');
|
1988
|
+
params = this.omit (params, 'chainName');
|
1989
|
+
const request = {
|
1990
|
+
'asset': currency['id'],
|
1991
|
+
};
|
1992
|
+
const response = await this.v1PrivateGetWalletDepositAddress (this.extend (request, params));
|
1993
|
+
//
|
1994
|
+
// {
|
1995
|
+
// "code":0,
|
1996
|
+
// "data":{
|
1997
|
+
// "asset":"USDT",
|
1998
|
+
// "assetName":"Tether",
|
1999
|
+
// "address":[
|
2000
|
+
// {
|
2001
|
+
// "address":"1N22odLHXnLPCjC8kwBJPTayarr9RtPod6",
|
2002
|
+
// "destTag":"",
|
2003
|
+
// "tagType":"",
|
2004
|
+
// "tagId":"",
|
2005
|
+
// "chainName":"Omni",
|
2006
|
+
// "numConfirmations":3,
|
2007
|
+
// "withdrawalFee":4.7,
|
2008
|
+
// "nativeScale":4,
|
2009
|
+
// "tips":[]
|
2010
|
+
// },
|
2011
|
+
// {
|
2012
|
+
// "address":"0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
|
2013
|
+
// "destTag":"",
|
2014
|
+
// "tagType":"",
|
2015
|
+
// "tagId":"",
|
2016
|
+
// "chainName":"ERC20",
|
2017
|
+
// "numConfirmations":20,
|
2018
|
+
// "withdrawalFee":1.0,
|
2019
|
+
// "nativeScale":4,
|
2020
|
+
// "tips":[]
|
2021
|
+
// }
|
2022
|
+
// ]
|
2023
|
+
// }
|
2024
|
+
// }
|
2025
|
+
//
|
2026
|
+
const data = this.safeValue (response, 'data', {});
|
2027
|
+
const addresses = this.safeValue (data, 'address', []);
|
2028
|
+
const numAddresses = addresses.length;
|
2029
|
+
let address = undefined;
|
2030
|
+
if (numAddresses > 1) {
|
2031
|
+
const addressesByChainName = this.indexBy (addresses, 'chainName');
|
2032
|
+
if (chainName === undefined) {
|
2033
|
+
const chainNames = Object.keys (addressesByChainName);
|
2034
|
+
const chains = chainNames.join (', ');
|
2035
|
+
throw new ArgumentsRequired (this.id + ' fetchDepositAddress() returned more than one address, a chainName parameter is required, one of ' + chains);
|
2036
|
+
}
|
2037
|
+
address = this.safeValue (addressesByChainName, chainName, {});
|
2038
|
+
} else {
|
2039
|
+
// first address
|
2040
|
+
address = this.safeValue (addresses, 0, {});
|
2041
|
+
}
|
2042
|
+
const result = this.parseDepositAddress (address, currency);
|
2043
|
+
return this.extend (result, {
|
2044
|
+
'info': response,
|
2045
|
+
});
|
2046
|
+
}
|
2047
|
+
|
2048
|
+
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2049
|
+
const request = {
|
2050
|
+
'txType': 'deposit',
|
2051
|
+
};
|
2052
|
+
return await this.fetchTransactions (code, since, limit, this.extend (request, params));
|
2053
|
+
}
|
2054
|
+
|
2055
|
+
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2056
|
+
const request = {
|
2057
|
+
'txType': 'withdrawal',
|
2058
|
+
};
|
2059
|
+
return await this.fetchTransactions (code, since, limit, this.extend (request, params));
|
2060
|
+
}
|
2061
|
+
|
2062
|
+
async fetchTransactions (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2063
|
+
await this.loadMarkets ();
|
2064
|
+
const request = {
|
2065
|
+
// 'asset': currency['id'],
|
2066
|
+
// 'page': 1,
|
2067
|
+
// 'pageSize': 20,
|
2068
|
+
// 'startTs': this.milliseconds (),
|
2069
|
+
// 'endTs': this.milliseconds (),
|
2070
|
+
// 'txType': undefned, // deposit, withdrawal
|
2071
|
+
};
|
2072
|
+
let currency = undefined;
|
2073
|
+
if (code !== undefined) {
|
2074
|
+
currency = this.currency (code);
|
2075
|
+
request['asset'] = currency['id'];
|
2076
|
+
}
|
2077
|
+
if (since !== undefined) {
|
2078
|
+
request['startTs'] = since;
|
2079
|
+
}
|
2080
|
+
if (limit !== undefined) {
|
2081
|
+
request['pageSize'] = limit;
|
2082
|
+
}
|
2083
|
+
const response = await this.v1PrivateGetWalletTransactions (this.extend (request, params));
|
2084
|
+
//
|
2085
|
+
// {
|
2086
|
+
// code: 0,
|
2087
|
+
// data: {
|
2088
|
+
// data: [
|
2089
|
+
// {
|
2090
|
+
// requestId: "wuzd1Ojsqtz4bCA3UXwtUnnJDmU8PiyB",
|
2091
|
+
// time: 1591606166000,
|
2092
|
+
// asset: "USDT",
|
2093
|
+
// transactionType: "deposit",
|
2094
|
+
// amount: "25",
|
2095
|
+
// commission: "0",
|
2096
|
+
// networkTransactionId: "0xbc4eabdce92f14dbcc01d799a5f8ca1f02f4a3a804b6350ea202be4d3c738fce",
|
2097
|
+
// status: "pending",
|
2098
|
+
// numConfirmed: 8,
|
2099
|
+
// numConfirmations: 20,
|
2100
|
+
// destAddress: { address: "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722" }
|
2101
|
+
// }
|
2102
|
+
// ],
|
2103
|
+
// page: 1,
|
2104
|
+
// pageSize: 20,
|
2105
|
+
// hasNext: false
|
2106
|
+
// }
|
2107
|
+
// }
|
2108
|
+
//
|
2109
|
+
const data = this.safeValue (response, 'data', {});
|
2110
|
+
const transactions = this.safeValue (data, 'data', []);
|
2111
|
+
return this.parseTransactions (transactions, currency, since, limit);
|
2112
|
+
}
|
2113
|
+
|
2114
|
+
parseTransactionStatus (status) {
|
2115
|
+
const statuses = {
|
2116
|
+
'reviewing': 'pending',
|
2117
|
+
'pending': 'pending',
|
2118
|
+
'confirmed': 'ok',
|
2119
|
+
'rejected': 'rejected',
|
2120
|
+
};
|
2121
|
+
return this.safeString (statuses, status, status);
|
2122
|
+
}
|
2123
|
+
|
2124
|
+
parseTransaction (transaction, currency = undefined) {
|
2125
|
+
//
|
2126
|
+
// {
|
2127
|
+
// requestId: "wuzd1Ojsqtz4bCA3UXwtUnnJDmU8PiyB",
|
2128
|
+
// time: 1591606166000,
|
2129
|
+
// asset: "USDT",
|
2130
|
+
// transactionType: "deposit",
|
2131
|
+
// amount: "25",
|
2132
|
+
// commission: "0",
|
2133
|
+
// networkTransactionId: "0xbc4eabdce92f14dbcc01d799a5f8ca1f02f4a3a804b6350ea202be4d3c738fce",
|
2134
|
+
// status: "pending",
|
2135
|
+
// numConfirmed: 8,
|
2136
|
+
// numConfirmations: 20,
|
2137
|
+
// destAddress: {
|
2138
|
+
// address: "0xe7c70b4e73b6b450ee46c3b5c0f5fb127ca55722",
|
2139
|
+
// destTag: "..." // for currencies that have it
|
2140
|
+
// }
|
2141
|
+
// }
|
2142
|
+
//
|
2143
|
+
const id = this.safeString (transaction, 'requestId');
|
2144
|
+
const amount = this.safeNumber (transaction, 'amount');
|
2145
|
+
const destAddress = this.safeValue (transaction, 'destAddress', {});
|
2146
|
+
const address = this.safeString (destAddress, 'address');
|
2147
|
+
const tag = this.safeString (destAddress, 'destTag');
|
2148
|
+
const txid = this.safeString (transaction, 'networkTransactionId');
|
2149
|
+
const type = this.safeString (transaction, 'transactionType');
|
2150
|
+
const timestamp = this.safeInteger (transaction, 'time');
|
2151
|
+
const currencyId = this.safeString (transaction, 'asset');
|
2152
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
2153
|
+
const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
|
2154
|
+
const feeCost = this.safeNumber (transaction, 'commission');
|
2155
|
+
return {
|
2156
|
+
'info': transaction,
|
2157
|
+
'id': id,
|
2158
|
+
'currency': code,
|
2159
|
+
'amount': amount,
|
2160
|
+
'network': undefined,
|
2161
|
+
'address': address,
|
2162
|
+
'addressTo': address,
|
2163
|
+
'addressFrom': undefined,
|
2164
|
+
'tag': tag,
|
2165
|
+
'tagTo': tag,
|
2166
|
+
'tagFrom': undefined,
|
2167
|
+
'status': status,
|
2168
|
+
'type': type,
|
2169
|
+
'updated': undefined,
|
2170
|
+
'txid': txid,
|
2171
|
+
'timestamp': timestamp,
|
2172
|
+
'datetime': this.iso8601 (timestamp),
|
2173
|
+
'fee': {
|
2174
|
+
'currency': code,
|
2175
|
+
'cost': feeCost,
|
2176
|
+
},
|
2177
|
+
};
|
2178
|
+
}
|
2179
|
+
|
2180
|
+
async fetchPositions (symbols = undefined, params = {}) {
|
2181
|
+
await this.loadMarkets ();
|
2182
|
+
await this.loadAccounts ();
|
2183
|
+
const account = this.safeValue (this.accounts, 0, {});
|
2184
|
+
const accountGroup = this.safeString (account, 'id');
|
2185
|
+
const request = {
|
2186
|
+
'account-group': accountGroup,
|
2187
|
+
};
|
2188
|
+
return await this.v2PrivateAccountGroupGetFuturesPosition (this.extend (request, params));
|
2189
|
+
}
|
2190
|
+
|
2191
|
+
parseFundingRate (fundingRate, market = undefined) {
|
2192
|
+
//
|
2193
|
+
// {
|
2194
|
+
// "time": 1640061364830,
|
2195
|
+
// "symbol": "EOS-PERP",
|
2196
|
+
// "markPrice": "3.353854865",
|
2197
|
+
// "indexPrice": "3.3542",
|
2198
|
+
// "openInterest": "14242",
|
2199
|
+
// "fundingRate": "-0.000073026",
|
2200
|
+
// "nextFundingTime": 1640073600000
|
2201
|
+
// }
|
2202
|
+
//
|
2203
|
+
const marketId = this.safeString (fundingRate, 'symbol');
|
2204
|
+
const symbol = this.safeSymbol (marketId, market);
|
2205
|
+
const currentTime = this.safeInteger (fundingRate, 'time');
|
2206
|
+
const nextFundingRate = this.safeNumber (fundingRate, 'fundingRate');
|
2207
|
+
const nextFundingRateTimestamp = this.safeInteger (fundingRate, 'nextFundingTime');
|
2208
|
+
const previousFundingTimestamp = undefined;
|
2209
|
+
return {
|
2210
|
+
'info': fundingRate,
|
2211
|
+
'symbol': symbol,
|
2212
|
+
'markPrice': this.safeNumber (fundingRate, 'markPrice'),
|
2213
|
+
'indexPrice': this.safeNumber (fundingRate, 'indexPrice'),
|
2214
|
+
'interestRate': this.parseNumber ('0'),
|
2215
|
+
'estimatedSettlePrice': undefined,
|
2216
|
+
'timestamp': currentTime,
|
2217
|
+
'datetime': this.iso8601 (currentTime),
|
2218
|
+
'previousFundingRate': undefined,
|
2219
|
+
'nextFundingRate': nextFundingRate,
|
2220
|
+
'previousFundingTimestamp': previousFundingTimestamp,
|
2221
|
+
'nextFundingTimestamp': nextFundingRateTimestamp,
|
2222
|
+
'previousFundingDatetime': this.iso8601 (previousFundingTimestamp),
|
2223
|
+
'nextFundingDatetime': this.iso8601 (nextFundingRateTimestamp),
|
2224
|
+
};
|
2225
|
+
}
|
2226
|
+
|
2227
|
+
async fetchFundingRates (symbols, params = {}) {
|
2228
|
+
await this.loadMarkets ();
|
2229
|
+
const response = await this.v2PublicGetFuturesPricingData (params);
|
2230
|
+
//
|
2231
|
+
// {
|
2232
|
+
// "code": 0,
|
2233
|
+
// "data": {
|
2234
|
+
// "contracts": [
|
2235
|
+
// {
|
2236
|
+
// "time": 1640061364830,
|
2237
|
+
// "symbol": "EOS-PERP",
|
2238
|
+
// "markPrice": "3.353854865",
|
2239
|
+
// "indexPrice": "3.3542",
|
2240
|
+
// "openInterest": "14242",
|
2241
|
+
// "fundingRate": "-0.000073026",
|
2242
|
+
// "nextFundingTime": 1640073600000
|
2243
|
+
// },
|
2244
|
+
// ],
|
2245
|
+
// "collaterals": [
|
2246
|
+
// {
|
2247
|
+
// "asset": "USDTR",
|
2248
|
+
// "referencePrice": "1"
|
2249
|
+
// },
|
2250
|
+
// ]
|
2251
|
+
// }
|
2252
|
+
// }
|
2253
|
+
//
|
2254
|
+
const data = this.safeValue (response, 'data', {});
|
2255
|
+
const contracts = this.safeValue (data, 'contracts', []);
|
2256
|
+
const result = this.parseFundingRates (contracts);
|
2257
|
+
return this.filterByArray (result, 'symbol', symbols);
|
2258
|
+
}
|
2259
|
+
|
2260
|
+
async modifyMarginHelper (symbol, amount, type, params = {}) {
|
2261
|
+
await this.loadMarkets ();
|
2262
|
+
await this.loadAccounts ();
|
2263
|
+
const market = this.market (symbol);
|
2264
|
+
const account = this.safeValue (this.accounts, 0, {});
|
2265
|
+
const accountGroup = this.safeString (account, 'id');
|
2266
|
+
amount = this.amountToPrecision (symbol, amount);
|
2267
|
+
const request = {
|
2268
|
+
'account-group': accountGroup,
|
2269
|
+
'symbol': market['id'],
|
2270
|
+
'amount': amount, // positive value for adding margin, negative for reducing
|
2271
|
+
};
|
2272
|
+
const response = await this.v2PrivateAccountGroupPostFuturesIsolatedPositionMargin (this.extend (request, params));
|
2273
|
+
//
|
2274
|
+
// Can only change margin for perpetual futures isolated margin positions
|
2275
|
+
//
|
2276
|
+
// {
|
2277
|
+
// "code": 0
|
2278
|
+
// }
|
2279
|
+
//
|
2280
|
+
if (type === 'reduce') {
|
2281
|
+
amount = Precise.stringAbs (amount);
|
2282
|
+
}
|
2283
|
+
return this.extend (this.parseModifyMargin (response, market), {
|
2284
|
+
'amount': this.parseNumber (amount),
|
2285
|
+
'type': type,
|
2286
|
+
});
|
2287
|
+
}
|
2288
|
+
|
2289
|
+
parseModifyMargin (data, market = undefined) {
|
2290
|
+
const errorCode = this.safeString (data, 'code');
|
2291
|
+
const status = (errorCode === '0') ? 'ok' : 'failed';
|
2292
|
+
return {
|
2293
|
+
'info': data,
|
2294
|
+
'type': undefined,
|
2295
|
+
'amount': undefined,
|
2296
|
+
'code': market['quote'],
|
2297
|
+
'symbol': market['symbol'],
|
2298
|
+
'status': status,
|
2299
|
+
};
|
2300
|
+
}
|
2301
|
+
|
2302
|
+
async reduceMargin (symbol, amount, params = {}) {
|
2303
|
+
return await this.modifyMarginHelper (symbol, amount, 'reduce', params);
|
2304
|
+
}
|
2305
|
+
|
2306
|
+
async addMargin (symbol, amount, params = {}) {
|
2307
|
+
return await this.modifyMarginHelper (symbol, amount, 'add', params);
|
2308
|
+
}
|
2309
|
+
|
2310
|
+
async setLeverage (leverage, symbol = undefined, params = {}) {
|
2311
|
+
if (symbol === undefined) {
|
2312
|
+
throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
|
2313
|
+
}
|
2314
|
+
if ((leverage < 1) || (leverage > 100)) {
|
2315
|
+
throw new BadRequest (this.id + ' leverage should be between 1 and 100');
|
2316
|
+
}
|
2317
|
+
await this.loadMarkets ();
|
2318
|
+
await this.loadAccounts ();
|
2319
|
+
const market = this.market (symbol);
|
2320
|
+
if (market['type'] !== 'future') {
|
2321
|
+
throw new BadSymbol (this.id + ' setLeverage() supports futures contracts only');
|
2322
|
+
}
|
2323
|
+
const account = this.safeValue (this.accounts, 0, {});
|
2324
|
+
const accountGroup = this.safeString (account, 'id');
|
2325
|
+
const request = {
|
2326
|
+
'account-group': accountGroup,
|
2327
|
+
'symbol': market['id'],
|
2328
|
+
'leverage': leverage,
|
2329
|
+
};
|
2330
|
+
return await this.v2PrivateAccountGroupPostFuturesLeverage (this.extend (request, params));
|
2331
|
+
}
|
2332
|
+
|
2333
|
+
async setMarginMode (marginType, symbol = undefined, params = {}) {
|
2334
|
+
marginType = marginType.toLowerCase ();
|
2335
|
+
if (marginType === 'cross') {
|
2336
|
+
marginType = 'crossed';
|
2337
|
+
}
|
2338
|
+
if (marginType !== 'isolated' && marginType !== 'crossed') {
|
2339
|
+
throw new BadRequest (this.id + ' setMarginMode() marginType argument should be isolated or cross');
|
2340
|
+
}
|
2341
|
+
await this.loadMarkets ();
|
2342
|
+
await this.loadAccounts ();
|
2343
|
+
const market = this.market (symbol);
|
2344
|
+
const account = this.safeValue (this.accounts, 0, {});
|
2345
|
+
const accountGroup = this.safeString (account, 'id');
|
2346
|
+
const request = {
|
2347
|
+
'account-group': accountGroup,
|
2348
|
+
'symbol': market['id'],
|
2349
|
+
'marginType': marginType,
|
2350
|
+
};
|
2351
|
+
if (market['type'] !== 'future') {
|
2352
|
+
throw new BadSymbol (this.id + ' setMarginMode() supports futures contracts only');
|
2353
|
+
}
|
2354
|
+
return await this.v2PrivateAccountGroupPostFuturesMarginType (this.extend (request, params));
|
2355
|
+
}
|
2356
|
+
|
2357
|
+
async fetchLeverageTiers (symbols = undefined, params = {}) {
|
2358
|
+
await this.loadMarkets ();
|
2359
|
+
const response = await this.v2PublicGetFuturesContract (params);
|
2360
|
+
//
|
2361
|
+
// {
|
2362
|
+
// "code":0,
|
2363
|
+
// "data":[
|
2364
|
+
// {
|
2365
|
+
// "symbol":"BTC-PERP",
|
2366
|
+
// "status":"Normal",
|
2367
|
+
// "displayName":"BTCUSDT",
|
2368
|
+
// "settlementAsset":"USDT",
|
2369
|
+
// "underlying":"BTC/USDT",
|
2370
|
+
// "tradingStartTime":1579701600000,
|
2371
|
+
// "priceFilter":{"minPrice":"1","maxPrice":"1000000","tickSize":"1"},
|
2372
|
+
// "lotSizeFilter":{"minQty":"0.0001","maxQty":"1000000000","lotSize":"0.0001"},
|
2373
|
+
// "commissionType":"Quote",
|
2374
|
+
// "commissionReserveRate":"0.001",
|
2375
|
+
// "marketOrderPriceMarkup":"0.03",
|
2376
|
+
// "marginRequirements":[
|
2377
|
+
// {"positionNotionalLowerBound":"0","positionNotionalUpperBound":"50000","initialMarginRate":"0.01","maintenanceMarginRate":"0.006"},
|
2378
|
+
// {"positionNotionalLowerBound":"50000","positionNotionalUpperBound":"200000","initialMarginRate":"0.02","maintenanceMarginRate":"0.012"},
|
2379
|
+
// {"positionNotionalLowerBound":"200000","positionNotionalUpperBound":"2000000","initialMarginRate":"0.04","maintenanceMarginRate":"0.024"},
|
2380
|
+
// {"positionNotionalLowerBound":"2000000","positionNotionalUpperBound":"20000000","initialMarginRate":"0.1","maintenanceMarginRate":"0.06"},
|
2381
|
+
// {"positionNotionalLowerBound":"20000000","positionNotionalUpperBound":"40000000","initialMarginRate":"0.2","maintenanceMarginRate":"0.12"},
|
2382
|
+
// {"positionNotionalLowerBound":"40000000","positionNotionalUpperBound":"1000000000","initialMarginRate":"0.333333","maintenanceMarginRate":"0.2"}
|
2383
|
+
// ]
|
2384
|
+
// }
|
2385
|
+
// ]
|
2386
|
+
// }
|
2387
|
+
//
|
2388
|
+
const data = this.safeValue (response, 'data');
|
2389
|
+
return this.parseLeverageTiers (data, symbols, 'symbol');
|
2390
|
+
}
|
2391
|
+
|
2392
|
+
parseMarketLeverageTiers (info, market = undefined) {
|
2393
|
+
/**
|
2394
|
+
* @param {dict} info Exchange market response for 1 market
|
2395
|
+
* @param {dict} market CCXT market
|
2396
|
+
*/
|
2397
|
+
//
|
2398
|
+
// {
|
2399
|
+
// "symbol":"BTC-PERP",
|
2400
|
+
// "status":"Normal",
|
2401
|
+
// "displayName":"BTCUSDT",
|
2402
|
+
// "settlementAsset":"USDT",
|
2403
|
+
// "underlying":"BTC/USDT",
|
2404
|
+
// "tradingStartTime":1579701600000,
|
2405
|
+
// "priceFilter":{"minPrice":"1","maxPrice":"1000000","tickSize":"1"},
|
2406
|
+
// "lotSizeFilter":{"minQty":"0.0001","maxQty":"1000000000","lotSize":"0.0001"},
|
2407
|
+
// "commissionType":"Quote",
|
2408
|
+
// "commissionReserveRate":"0.001",
|
2409
|
+
// "marketOrderPriceMarkup":"0.03",
|
2410
|
+
// "marginRequirements":[
|
2411
|
+
// {"positionNotionalLowerBound":"0","positionNotionalUpperBound":"50000","initialMarginRate":"0.01","maintenanceMarginRate":"0.006"},
|
2412
|
+
// {"positionNotionalLowerBound":"50000","positionNotionalUpperBound":"200000","initialMarginRate":"0.02","maintenanceMarginRate":"0.012"},
|
2413
|
+
// {"positionNotionalLowerBound":"200000","positionNotionalUpperBound":"2000000","initialMarginRate":"0.04","maintenanceMarginRate":"0.024"},
|
2414
|
+
// {"positionNotionalLowerBound":"2000000","positionNotionalUpperBound":"20000000","initialMarginRate":"0.1","maintenanceMarginRate":"0.06"},
|
2415
|
+
// {"positionNotionalLowerBound":"20000000","positionNotionalUpperBound":"40000000","initialMarginRate":"0.2","maintenanceMarginRate":"0.12"},
|
2416
|
+
// {"positionNotionalLowerBound":"40000000","positionNotionalUpperBound":"1000000000","initialMarginRate":"0.333333","maintenanceMarginRate":"0.2"}
|
2417
|
+
// ]
|
2418
|
+
// }
|
2419
|
+
//
|
2420
|
+
const marginRequirements = this.safeValue (info, 'marginRequirements');
|
2421
|
+
const id = this.safeString (info, 'symbol');
|
2422
|
+
market = this.safeMarket (id, market);
|
2423
|
+
const tiers = [];
|
2424
|
+
for (let i = 0; i < marginRequirements.length; i++) {
|
2425
|
+
const tier = marginRequirements[i];
|
2426
|
+
const initialMarginRate = this.safeString (tier, 'initialMarginRate');
|
2427
|
+
tiers.push ({
|
2428
|
+
'tier': this.sum (i, 1),
|
2429
|
+
'currency': market['quote'],
|
2430
|
+
'minNotional': this.safeNumber (tier, 'positionNotionalLowerBound'),
|
2431
|
+
'maxNotional': this.safeNumber (tier, 'positionNotionalUpperBound'),
|
2432
|
+
'maintenanceMarginRate': this.safeNumber (tier, 'maintenanceMarginRate'),
|
2433
|
+
'maxLeverage': this.parseNumber (Precise.stringDiv ('1', initialMarginRate)),
|
2434
|
+
'info': tier,
|
2435
|
+
});
|
2436
|
+
}
|
2437
|
+
return tiers;
|
2438
|
+
}
|
2439
|
+
|
2440
|
+
async transfer (code, amount, fromAccount, toAccount, params = {}) {
|
2441
|
+
await this.loadMarkets ();
|
2442
|
+
await this.loadAccounts ();
|
2443
|
+
const account = this.safeValue (this.accounts, 0, {});
|
2444
|
+
const accountGroup = this.safeString (account, 'id');
|
2445
|
+
const currency = this.currency (code);
|
2446
|
+
amount = this.currencyToPrecision (code, amount);
|
2447
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
2448
|
+
const fromId = this.safeString (accountsByType, fromAccount, fromAccount);
|
2449
|
+
const toId = this.safeString (accountsByType, toAccount, toAccount);
|
2450
|
+
if (fromId !== 'cash' && toId !== 'cash') {
|
2451
|
+
throw new ExchangeError (this.id + ' transfer() only supports direct balance transfer between spot and future, spot and margin');
|
2452
|
+
}
|
2453
|
+
const request = {
|
2454
|
+
'account-group': accountGroup,
|
2455
|
+
'amount': amount,
|
2456
|
+
'asset': currency['id'],
|
2457
|
+
'fromAccount': fromId,
|
2458
|
+
'toAccount': toId,
|
2459
|
+
};
|
2460
|
+
const response = await this.v1PrivateAccountGroupPostTransfer (this.extend (request, params));
|
2461
|
+
//
|
2462
|
+
// { code: '0' }
|
2463
|
+
//
|
2464
|
+
const transferOptions = this.safeValue (this.options, 'transfer', {});
|
2465
|
+
const fillResponseFromRequest = this.safeValue (transferOptions, 'fillResponseFromRequest', true);
|
2466
|
+
const transfer = this.parseTransfer (response, currency);
|
2467
|
+
if (fillResponseFromRequest) {
|
2468
|
+
transfer['fromAccount'] = fromAccount;
|
2469
|
+
transfer['toAccount'] = toAccount;
|
2470
|
+
transfer['amount'] = amount;
|
2471
|
+
transfer['currency'] = code;
|
2472
|
+
}
|
2473
|
+
return transfer;
|
2474
|
+
}
|
2475
|
+
|
2476
|
+
parseTransfer (transfer, currency = undefined) {
|
2477
|
+
//
|
2478
|
+
// { code: '0' }
|
2479
|
+
//
|
2480
|
+
const status = this.safeInteger (transfer, 'code');
|
2481
|
+
const currencyCode = this.safeCurrencyCode (undefined, currency);
|
2482
|
+
const timestamp = this.milliseconds ();
|
2483
|
+
return {
|
2484
|
+
'info': transfer,
|
2485
|
+
'id': undefined,
|
2486
|
+
'timestamp': timestamp,
|
2487
|
+
'datetime': this.iso8601 (timestamp),
|
2488
|
+
'currency': currencyCode,
|
2489
|
+
'amount': undefined,
|
2490
|
+
'fromAccount': undefined,
|
2491
|
+
'toAccount': undefined,
|
2492
|
+
'status': this.parseTransferStatus (status),
|
2493
|
+
};
|
2494
|
+
}
|
2495
|
+
|
2496
|
+
parseTransferStatus (status) {
|
2497
|
+
if (status === 0) {
|
2498
|
+
return 'ok';
|
2499
|
+
}
|
2500
|
+
return 'failed';
|
2501
|
+
}
|
2502
|
+
|
2503
|
+
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
2504
|
+
const version = api[0];
|
2505
|
+
const access = api[1];
|
2506
|
+
const type = this.safeString (api, 2);
|
2507
|
+
let url = '';
|
2508
|
+
const accountCategory = (type === 'accountCategory');
|
2509
|
+
if (accountCategory || (type === 'accountGroup')) {
|
2510
|
+
url += this.implodeParams ('/{account-group}', params);
|
2511
|
+
params = this.omit (params, 'account-group');
|
2512
|
+
}
|
2513
|
+
let request = this.implodeParams (path, params);
|
2514
|
+
url += '/api/pro/';
|
2515
|
+
if (version === 'v2') {
|
2516
|
+
request = version + '/' + request;
|
2517
|
+
} else {
|
2518
|
+
url += version + '/';
|
2519
|
+
}
|
2520
|
+
if (accountCategory) {
|
2521
|
+
url += this.implodeParams ('{account-category}/', params);
|
2522
|
+
}
|
2523
|
+
params = this.omit (params, 'account-category');
|
2524
|
+
url += request;
|
2525
|
+
if ((version === 'v1') && (request === 'cash/balance') || (request === 'margin/balance')) {
|
2526
|
+
request = 'balance';
|
2527
|
+
}
|
2528
|
+
if ((version === 'v1') && (request === 'spot/fee')) {
|
2529
|
+
request = 'fee';
|
2530
|
+
}
|
2531
|
+
if (request.indexOf ('subuser') >= 0) {
|
2532
|
+
const parts = request.split ('/');
|
2533
|
+
request = parts[2];
|
2534
|
+
}
|
2535
|
+
params = this.omit (params, this.extractParams (path));
|
2536
|
+
if (access === 'public') {
|
2537
|
+
if (Object.keys (params).length) {
|
2538
|
+
url += '?' + this.urlencode (params);
|
2539
|
+
}
|
2540
|
+
} else {
|
2541
|
+
this.checkRequiredCredentials ();
|
2542
|
+
const timestamp = this.milliseconds ().toString ();
|
2543
|
+
const payload = timestamp + '+' + request;
|
2544
|
+
const hmac = this.hmac (this.encode (payload), this.encode (this.secret), 'sha256', 'base64');
|
2545
|
+
headers = {
|
2546
|
+
'x-auth-key': this.apiKey,
|
2547
|
+
'x-auth-timestamp': timestamp,
|
2548
|
+
'x-auth-signature': hmac,
|
2549
|
+
};
|
2550
|
+
if (method === 'GET') {
|
2551
|
+
if (Object.keys (params).length) {
|
2552
|
+
url += '?' + this.urlencode (params);
|
2553
|
+
}
|
2554
|
+
} else {
|
2555
|
+
headers['Content-Type'] = 'application/json';
|
2556
|
+
body = this.json (params);
|
2557
|
+
}
|
2558
|
+
}
|
2559
|
+
url = this.urls['api']['rest'] + url;
|
2560
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
2561
|
+
}
|
2562
|
+
|
2563
|
+
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
2564
|
+
if (response === undefined) {
|
2565
|
+
return; // fallback to default error handler
|
2566
|
+
}
|
2567
|
+
//
|
2568
|
+
// {'code': 6010, 'message': 'Not enough balance.'}
|
2569
|
+
// {'code': 60060, 'message': 'The order is already filled or canceled.'}
|
2570
|
+
// {"code":2100,"message":"ApiKeyFailure"}
|
2571
|
+
// {"code":300001,"message":"Price is too low from market price.","reason":"INVALID_PRICE","accountId":"cshrHKLZCjlZ2ejqkmvIHHtPmLYqdnda","ac":"CASH","action":"place-order","status":"Err","info":{"symbol":"BTC/USDT"}}
|
2572
|
+
//
|
2573
|
+
const code = this.safeString (response, 'code');
|
2574
|
+
const message = this.safeString (response, 'message');
|
2575
|
+
const error = (code !== undefined) && (code !== '0');
|
2576
|
+
if (error || (message !== undefined)) {
|
2577
|
+
const feedback = this.id + ' ' + body;
|
2578
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], code, feedback);
|
2579
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], message, feedback);
|
2580
|
+
this.throwBroadlyMatchedException (this.exceptions['broad'], message, feedback);
|
2581
|
+
throw new ExchangeError (feedback); // unknown message
|
2582
|
+
}
|
2583
|
+
}
|
2584
|
+
};
|