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/gateio.js
ADDED
@@ -0,0 +1,4174 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const Precise = require ('./base/Precise');
|
7
|
+
const { TICK_SIZE } = require ('./base/functions/number');
|
8
|
+
const { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled } = require ('./base/errors');
|
9
|
+
|
10
|
+
module.exports = class gateio extends Exchange {
|
11
|
+
describe () {
|
12
|
+
return this.deepExtend (super.describe (), {
|
13
|
+
'id': 'gateio',
|
14
|
+
'name': 'Gate.io',
|
15
|
+
'countries': [ 'KR' ],
|
16
|
+
'rateLimit': 10 / 3, // 300 requests per second or 3.33ms
|
17
|
+
'version': 'v4',
|
18
|
+
'certified': true,
|
19
|
+
'pro': true,
|
20
|
+
'urls': {
|
21
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg',
|
22
|
+
'doc': 'https://www.gate.io/docs/apiv4/en/index.html',
|
23
|
+
'www': 'https://gate.io/',
|
24
|
+
'api': {
|
25
|
+
'public': {
|
26
|
+
'wallet': 'https://api.gateio.ws/api/v4',
|
27
|
+
'futures': 'https://api.gateio.ws/api/v4',
|
28
|
+
'margin': 'https://api.gateio.ws/api/v4',
|
29
|
+
'delivery': 'https://api.gateio.ws/api/v4',
|
30
|
+
'spot': 'https://api.gateio.ws/api/v4',
|
31
|
+
'options': 'https://api.gateio.ws/api/v4',
|
32
|
+
},
|
33
|
+
'private': {
|
34
|
+
'withdrawals': 'https://api.gateio.ws/api/v4',
|
35
|
+
'wallet': 'https://api.gateio.ws/api/v4',
|
36
|
+
'futures': 'https://api.gateio.ws/api/v4',
|
37
|
+
'margin': 'https://api.gateio.ws/api/v4',
|
38
|
+
'delivery': 'https://api.gateio.ws/api/v4',
|
39
|
+
'spot': 'https://api.gateio.ws/api/v4',
|
40
|
+
'options': 'https://api.gateio.ws/api/v4',
|
41
|
+
},
|
42
|
+
},
|
43
|
+
'test': {
|
44
|
+
'public': {
|
45
|
+
'futures': 'https://fx-api-testnet.gateio.ws/api/v4',
|
46
|
+
'delivery': 'https://fx-api-testnet.gateio.ws/api/v4',
|
47
|
+
},
|
48
|
+
'private': {
|
49
|
+
'futures': 'https://fx-api-testnet.gateio.ws/api/v4',
|
50
|
+
'delivery': 'https://fx-api-testnet.gateio.ws/api/v4',
|
51
|
+
},
|
52
|
+
},
|
53
|
+
'referral': {
|
54
|
+
'url': 'https://www.gate.io/ref/2436035',
|
55
|
+
'discount': 0.2,
|
56
|
+
},
|
57
|
+
},
|
58
|
+
'has': {
|
59
|
+
'CORS': undefined,
|
60
|
+
'spot': true,
|
61
|
+
'margin': true,
|
62
|
+
'swap': true,
|
63
|
+
'future': true,
|
64
|
+
'option': undefined,
|
65
|
+
'cancelAllOrders': true,
|
66
|
+
'cancelOrder': true,
|
67
|
+
'createMarketOrder': false,
|
68
|
+
'createOrder': true,
|
69
|
+
'createPostOnlyOrder': true,
|
70
|
+
'createStopLimitOrder': true,
|
71
|
+
'createStopMarketOrder': false,
|
72
|
+
'createStopOrder': true,
|
73
|
+
'fetchBalance': true,
|
74
|
+
'fetchBorrowRate': false,
|
75
|
+
'fetchBorrowRateHistories': false,
|
76
|
+
'fetchBorrowRateHistory': false,
|
77
|
+
'fetchBorrowRates': false,
|
78
|
+
'fetchClosedOrders': true,
|
79
|
+
'fetchCurrencies': true,
|
80
|
+
'fetchDepositAddress': true,
|
81
|
+
'fetchDeposits': true,
|
82
|
+
'fetchFundingFees': true,
|
83
|
+
'fetchFundingHistory': true,
|
84
|
+
'fetchFundingRate': true,
|
85
|
+
'fetchFundingRateHistory': true,
|
86
|
+
'fetchFundingRates': true,
|
87
|
+
'fetchIndexOHLCV': true,
|
88
|
+
'fetchLeverage': false,
|
89
|
+
'fetchLeverageTiers': true,
|
90
|
+
'fetchMarketLeverageTiers': 'emulated',
|
91
|
+
'fetchMarkets': true,
|
92
|
+
'fetchMarkOHLCV': true,
|
93
|
+
'fetchMyTrades': true,
|
94
|
+
'fetchNetworkDepositAddress': true,
|
95
|
+
'fetchOHLCV': true,
|
96
|
+
'fetchOpenOrders': true,
|
97
|
+
'fetchOrder': true,
|
98
|
+
'fetchOrderBook': true,
|
99
|
+
'fetchPositions': true,
|
100
|
+
'fetchPremiumIndexOHLCV': false,
|
101
|
+
'fetchTicker': true,
|
102
|
+
'fetchTickers': true,
|
103
|
+
'fetchTime': false,
|
104
|
+
'fetchTrades': true,
|
105
|
+
'fetchTradingFee': true,
|
106
|
+
'fetchTradingFees': true,
|
107
|
+
'fetchWithdrawals': true,
|
108
|
+
'setLeverage': true,
|
109
|
+
'setMarginMode': false,
|
110
|
+
'transfer': true,
|
111
|
+
'withdraw': true,
|
112
|
+
},
|
113
|
+
'api': {
|
114
|
+
'public': {
|
115
|
+
'wallet': {
|
116
|
+
'get': {
|
117
|
+
'wallet/currency_chains': 1.5,
|
118
|
+
},
|
119
|
+
},
|
120
|
+
'spot': {
|
121
|
+
'get': {
|
122
|
+
'currencies': 1,
|
123
|
+
'currencies/{currency}': 1,
|
124
|
+
'currency_pairs': 1,
|
125
|
+
'currency_pairs/{currency_pair}': 1,
|
126
|
+
'tickers': 1,
|
127
|
+
'order_book': 1,
|
128
|
+
'trades': 1,
|
129
|
+
'candlesticks': 1,
|
130
|
+
},
|
131
|
+
},
|
132
|
+
'margin': {
|
133
|
+
'get': {
|
134
|
+
'currency_pairs': 1,
|
135
|
+
'currency_pairs/{currency_pair}': 1,
|
136
|
+
'cross/currencies': 1,
|
137
|
+
'cross/currencies/{currency}': 1,
|
138
|
+
'funding_book': 1,
|
139
|
+
},
|
140
|
+
},
|
141
|
+
'futures': {
|
142
|
+
'get': {
|
143
|
+
'{settle}/contracts': 1.5,
|
144
|
+
'{settle}/contracts/{contract}': 1.5,
|
145
|
+
'{settle}/order_book': 1.5,
|
146
|
+
'{settle}/trades': 1.5,
|
147
|
+
'{settle}/candlesticks': 1.5,
|
148
|
+
'{settle}/tickers': 1.5,
|
149
|
+
'{settle}/funding_rate': 1.5,
|
150
|
+
'{settle}/insurance': 1.5,
|
151
|
+
'{settle}/contract_stats': 1.5,
|
152
|
+
'{settle}/liq_orders': 1.5,
|
153
|
+
},
|
154
|
+
},
|
155
|
+
'delivery': {
|
156
|
+
'get': {
|
157
|
+
'{settle}/contracts': 1.5,
|
158
|
+
'{settle}/contracts/{contract}': 1.5,
|
159
|
+
'{settle}/order_book': 1.5,
|
160
|
+
'{settle}/trades': 1.5,
|
161
|
+
'{settle}/candlesticks': 1.5,
|
162
|
+
'{settle}/tickers': 1.5,
|
163
|
+
'{settle}/insurance': 1.5,
|
164
|
+
},
|
165
|
+
},
|
166
|
+
'options': {
|
167
|
+
'get': {
|
168
|
+
'underlyings': 1.5,
|
169
|
+
'expirations': 1.5,
|
170
|
+
'contracts': 1.5,
|
171
|
+
'contracts/{contract}': 1.5,
|
172
|
+
'settlements': 1.5,
|
173
|
+
'settlements/{contract}': 1.5,
|
174
|
+
'order_book': 1.5,
|
175
|
+
'tickers': 1.5,
|
176
|
+
'underlying/tickers/{underlying}': 1.5,
|
177
|
+
'candlesticks': 1.5,
|
178
|
+
'underlying/candlesticks': 1.5,
|
179
|
+
'trades': 1.5,
|
180
|
+
},
|
181
|
+
},
|
182
|
+
},
|
183
|
+
'private': {
|
184
|
+
'withdrawals': {
|
185
|
+
'post': {
|
186
|
+
'': 3000, // 3000 = 10 seconds
|
187
|
+
},
|
188
|
+
'delete': {
|
189
|
+
'{withdrawal_id}': 300,
|
190
|
+
},
|
191
|
+
},
|
192
|
+
'wallet': {
|
193
|
+
'get': {
|
194
|
+
'deposit_address': 300,
|
195
|
+
'withdrawals': 300,
|
196
|
+
'deposits': 300,
|
197
|
+
'sub_account_transfers': 300,
|
198
|
+
'withdraw_status': 300,
|
199
|
+
'sub_account_balances': 300,
|
200
|
+
'fee': 300,
|
201
|
+
'total_balance': 300,
|
202
|
+
},
|
203
|
+
'post': {
|
204
|
+
'transfers': 300,
|
205
|
+
'sub_account_transfers': 300,
|
206
|
+
},
|
207
|
+
},
|
208
|
+
'spot': {
|
209
|
+
'get': {
|
210
|
+
'accounts': 1,
|
211
|
+
'open_orders': 1,
|
212
|
+
'orders': 1,
|
213
|
+
'orders/{order_id}': 1,
|
214
|
+
'my_trades': 1,
|
215
|
+
'price_orders': 1,
|
216
|
+
'price_orders/{order_id}': 1,
|
217
|
+
},
|
218
|
+
'post': {
|
219
|
+
'batch_orders': 1,
|
220
|
+
'orders': 1,
|
221
|
+
'cancel_batch_orders': 1,
|
222
|
+
'price_orders': 1,
|
223
|
+
},
|
224
|
+
'delete': {
|
225
|
+
'orders': 1,
|
226
|
+
'orders/{order_id}': 1,
|
227
|
+
'price_orders': 1,
|
228
|
+
'price_orders/{order_id}': 1,
|
229
|
+
},
|
230
|
+
},
|
231
|
+
'margin': {
|
232
|
+
'get': {
|
233
|
+
'accounts': 1.5,
|
234
|
+
'account_book': 1.5,
|
235
|
+
'funding_accounts': 1.5,
|
236
|
+
'loans': 1.5,
|
237
|
+
'loans/{loan_id}': 1.5,
|
238
|
+
'loans/{loan_id}/repayment': 1.5,
|
239
|
+
'loan_records': 1.5,
|
240
|
+
'loan_records/{load_record_id}': 1.5,
|
241
|
+
'auto_repay': 1.5,
|
242
|
+
'transferable': 1.5,
|
243
|
+
'cross/accounts': 1.5,
|
244
|
+
'cross/account_book': 1.5,
|
245
|
+
'cross/loans': 1.5,
|
246
|
+
'cross/loans/{loan_id}': 1.5,
|
247
|
+
'cross/loans/repayments': 1.5,
|
248
|
+
'cross/transferable': 1.5,
|
249
|
+
'loan_records/{loan_record_id}': 1.5,
|
250
|
+
'borrowable': 1.5,
|
251
|
+
'cross/repayments': 1.5,
|
252
|
+
'cross/borrowable': 1.5,
|
253
|
+
},
|
254
|
+
'post': {
|
255
|
+
'loans': 1.5,
|
256
|
+
'merged_loans': 1.5,
|
257
|
+
'loans/{loan_id}/repayment': 1.5,
|
258
|
+
'auto_repay': 1.5,
|
259
|
+
'cross/loans': 1.5,
|
260
|
+
'cross/loans/repayments': 1.5,
|
261
|
+
'cross/repayments': 1.5,
|
262
|
+
},
|
263
|
+
'patch': {
|
264
|
+
'loans/{loan_id}': 1.5,
|
265
|
+
'loan_records/{loan_record_id}': 1.5,
|
266
|
+
},
|
267
|
+
'delete': {
|
268
|
+
'loans/{loan_id}': 1.5,
|
269
|
+
},
|
270
|
+
},
|
271
|
+
'futures': {
|
272
|
+
'get': {
|
273
|
+
'{settle}/accounts': 1.5,
|
274
|
+
'{settle}/account_book': 1.5,
|
275
|
+
'{settle}/positions': 1.5,
|
276
|
+
'{settle}/positions/{contract}': 1.5,
|
277
|
+
'{settle}/orders': 1.5,
|
278
|
+
'{settle}/orders/{order_id}': 1.5,
|
279
|
+
'{settle}/my_trades': 1.5,
|
280
|
+
'{settle}/position_close': 1.5,
|
281
|
+
'{settle}/liquidates': 1.5,
|
282
|
+
'{settle}/price_orders': 1.5,
|
283
|
+
'{settle}/price_orders/{order_id}': 1.5,
|
284
|
+
'{settle}/dual_comp/positions/{contract}': 1.5,
|
285
|
+
},
|
286
|
+
'post': {
|
287
|
+
'{settle}/positions/{contract}/margin': 1.5,
|
288
|
+
'{settle}/positions/{contract}/leverage': 1.5,
|
289
|
+
'{settle}/positions/{contract}/risk_limit': 1.5,
|
290
|
+
'{settle}/dual_mode': 1.5,
|
291
|
+
'{settle}/dual_comp/positions/{contract}': 1.5,
|
292
|
+
'{settle}/dual_comp/positions/{contract}/margin': 1.5,
|
293
|
+
'{settle}/dual_comp/positions/{contract}/leverage': 1.5,
|
294
|
+
'{settle}/dual_comp/positions/{contract}/risk_limit': 1.5,
|
295
|
+
'{settle}/orders': 1.5,
|
296
|
+
'{settle}/price_orders': 1.5,
|
297
|
+
},
|
298
|
+
'delete': {
|
299
|
+
'{settle}/orders': 1.5,
|
300
|
+
'{settle}/orders/{order_id}': 1.5,
|
301
|
+
'{settle}/price_orders': 1.5,
|
302
|
+
'{settle}/price_orders/{order_id}': 1.5,
|
303
|
+
},
|
304
|
+
},
|
305
|
+
'delivery': {
|
306
|
+
'get': {
|
307
|
+
'{settle}/accounts': 1.5,
|
308
|
+
'{settle}/account_book': 1.5,
|
309
|
+
'{settle}/positions': 1.5,
|
310
|
+
'{settle}/positions/{contract}': 1.5,
|
311
|
+
'{settle}/orders': 1.5,
|
312
|
+
'{settle}/orders/{order_id}': 1.5,
|
313
|
+
'{settle}/my_trades': 1.5,
|
314
|
+
'{settle}/position_close': 1.5,
|
315
|
+
'{settle}/liquidates': 1.5,
|
316
|
+
'{settle}/price_orders': 1.5,
|
317
|
+
'{settle}/price_orders/{order_id}': 1.5,
|
318
|
+
'{settle}/settlements': 1.5,
|
319
|
+
},
|
320
|
+
'post': {
|
321
|
+
'{settle}/positions/{contract}/margin': 1.5,
|
322
|
+
'{settle}/positions/{contract}/leverage': 1.5,
|
323
|
+
'{settle}/positions/{contract}/risk_limit': 1.5,
|
324
|
+
'{settle}/orders': 1.5,
|
325
|
+
'{settle}/price_orders': 1.5,
|
326
|
+
},
|
327
|
+
'delete': {
|
328
|
+
'{settle}/orders': 1.5,
|
329
|
+
'{settle}/orders/{order_id}': 1.5,
|
330
|
+
'{settle}/price_orders': 1.5,
|
331
|
+
'{settle}/price_orders/{order_id}': 1.5,
|
332
|
+
},
|
333
|
+
},
|
334
|
+
'options': {
|
335
|
+
'get': {
|
336
|
+
'accounts': 1.5,
|
337
|
+
'account_book': 1.5,
|
338
|
+
'positions': 1.5,
|
339
|
+
'positions/{contract}': 1.5,
|
340
|
+
'position_close': 1.5,
|
341
|
+
'orders': 1.5,
|
342
|
+
'orders/{order_id}': 1.5,
|
343
|
+
'my_trades': 1.5,
|
344
|
+
},
|
345
|
+
'post': {
|
346
|
+
'orders': 1.5,
|
347
|
+
},
|
348
|
+
'delete': {
|
349
|
+
'orders': 1.5,
|
350
|
+
'orders/{order_id}': 1.5,
|
351
|
+
},
|
352
|
+
},
|
353
|
+
},
|
354
|
+
},
|
355
|
+
'timeframes': {
|
356
|
+
'10s': '10s',
|
357
|
+
'1m': '1m',
|
358
|
+
'5m': '5m',
|
359
|
+
'15m': '15m',
|
360
|
+
'30m': '30m',
|
361
|
+
'1h': '1h',
|
362
|
+
'4h': '4h',
|
363
|
+
'8h': '8h',
|
364
|
+
'1d': '1d',
|
365
|
+
'7d': '7d',
|
366
|
+
'1w': '7d',
|
367
|
+
},
|
368
|
+
// copied from gateiov2
|
369
|
+
'commonCurrencies': {
|
370
|
+
'88MPH': 'MPH',
|
371
|
+
'AXIS': 'Axis DeFi',
|
372
|
+
'BIFI': 'Bitcoin File',
|
373
|
+
'BOX': 'DefiBox',
|
374
|
+
'BTCBEAR': 'BEAR',
|
375
|
+
'BTCBULL': 'BULL',
|
376
|
+
'BYN': 'BeyondFi',
|
377
|
+
'EGG': 'Goose Finance',
|
378
|
+
'GTC': 'Game.com', // conflict with Gitcoin and Gastrocoin
|
379
|
+
'GTC_HT': 'Game.com HT',
|
380
|
+
'GTC_BSC': 'Game.com BSC',
|
381
|
+
'HIT': 'HitChain',
|
382
|
+
'MM': 'Million', // conflict with MilliMeter
|
383
|
+
'MPH': 'Morpher', // conflict with 88MPH
|
384
|
+
'RAI': 'Rai Reflex Index', // conflict with RAI Finance
|
385
|
+
'SBTC': 'Super Bitcoin',
|
386
|
+
'TNC': 'Trinity Network Credit',
|
387
|
+
'TON': 'TONToken',
|
388
|
+
'VAI': 'VAIOT',
|
389
|
+
},
|
390
|
+
'requiredCredentials': {
|
391
|
+
'apiKey': true,
|
392
|
+
'secret': true,
|
393
|
+
},
|
394
|
+
'headers': {
|
395
|
+
'X-Gate-Channel-Id': 'ccxt',
|
396
|
+
},
|
397
|
+
'options': {
|
398
|
+
'createOrder': {
|
399
|
+
'expiration': 86400, // for conditional orders
|
400
|
+
},
|
401
|
+
'networks': {
|
402
|
+
'TRC20': 'TRX',
|
403
|
+
'ERC20': 'ETH',
|
404
|
+
'BEP20': 'BSC',
|
405
|
+
},
|
406
|
+
'accountsByType': {
|
407
|
+
'funding': 'spot',
|
408
|
+
'spot': 'spot',
|
409
|
+
'margin': 'margin',
|
410
|
+
'cross_margin': 'cross_margin',
|
411
|
+
'cross': 'cross_margin',
|
412
|
+
'isolated': 'margin',
|
413
|
+
'swap': 'futures',
|
414
|
+
'future': 'delivery',
|
415
|
+
'futures': 'futures',
|
416
|
+
'delivery': 'delivery',
|
417
|
+
},
|
418
|
+
'defaultType': 'spot',
|
419
|
+
'swap': {
|
420
|
+
'fetchMarkets': {
|
421
|
+
'settlementCurrencies': [ 'usdt', 'btc' ],
|
422
|
+
},
|
423
|
+
},
|
424
|
+
'future': {
|
425
|
+
'fetchMarkets': {
|
426
|
+
'settlementCurrencies': [ 'usdt', 'btc' ],
|
427
|
+
},
|
428
|
+
},
|
429
|
+
},
|
430
|
+
'precisionMode': TICK_SIZE,
|
431
|
+
'fees': {
|
432
|
+
'trading': {
|
433
|
+
'tierBased': true,
|
434
|
+
'feeSide': 'get',
|
435
|
+
'percentage': true,
|
436
|
+
'maker': this.parseNumber ('0.002'),
|
437
|
+
'taker': this.parseNumber ('0.002'),
|
438
|
+
'tiers': {
|
439
|
+
// volume is in BTC
|
440
|
+
'maker': [
|
441
|
+
[ this.parseNumber ('0'), this.parseNumber ('0.002') ],
|
442
|
+
[ this.parseNumber ('1.5'), this.parseNumber ('0.00185') ],
|
443
|
+
[ this.parseNumber ('3'), this.parseNumber ('0.00175') ],
|
444
|
+
[ this.parseNumber ('6'), this.parseNumber ('0.00165') ],
|
445
|
+
[ this.parseNumber ('12.5'), this.parseNumber ('0.00155') ],
|
446
|
+
[ this.parseNumber ('25'), this.parseNumber ('0.00145') ],
|
447
|
+
[ this.parseNumber ('75'), this.parseNumber ('0.00135') ],
|
448
|
+
[ this.parseNumber ('200'), this.parseNumber ('0.00125') ],
|
449
|
+
[ this.parseNumber ('500'), this.parseNumber ('0.00115') ],
|
450
|
+
[ this.parseNumber ('1250'), this.parseNumber ('0.00105') ],
|
451
|
+
[ this.parseNumber ('2500'), this.parseNumber ('0.00095') ],
|
452
|
+
[ this.parseNumber ('3000'), this.parseNumber ('0.00085') ],
|
453
|
+
[ this.parseNumber ('6000'), this.parseNumber ('0.00075') ],
|
454
|
+
[ this.parseNumber ('11000'), this.parseNumber ('0.00065') ],
|
455
|
+
[ this.parseNumber ('20000'), this.parseNumber ('0.00055') ],
|
456
|
+
[ this.parseNumber ('40000'), this.parseNumber ('0.00055') ],
|
457
|
+
[ this.parseNumber ('75000'), this.parseNumber ('0.00055') ],
|
458
|
+
],
|
459
|
+
'taker': [
|
460
|
+
[ this.parseNumber ('0'), this.parseNumber ('0.002') ],
|
461
|
+
[ this.parseNumber ('1.5'), this.parseNumber ('0.00195') ],
|
462
|
+
[ this.parseNumber ('3'), this.parseNumber ('0.00185') ],
|
463
|
+
[ this.parseNumber ('6'), this.parseNumber ('0.00175') ],
|
464
|
+
[ this.parseNumber ('12.5'), this.parseNumber ('0.00165') ],
|
465
|
+
[ this.parseNumber ('25'), this.parseNumber ('0.00155') ],
|
466
|
+
[ this.parseNumber ('75'), this.parseNumber ('0.00145') ],
|
467
|
+
[ this.parseNumber ('200'), this.parseNumber ('0.00135') ],
|
468
|
+
[ this.parseNumber ('500'), this.parseNumber ('0.00125') ],
|
469
|
+
[ this.parseNumber ('1250'), this.parseNumber ('0.00115') ],
|
470
|
+
[ this.parseNumber ('2500'), this.parseNumber ('0.00105') ],
|
471
|
+
[ this.parseNumber ('3000'), this.parseNumber ('0.00095') ],
|
472
|
+
[ this.parseNumber ('6000'), this.parseNumber ('0.00085') ],
|
473
|
+
[ this.parseNumber ('11000'), this.parseNumber ('0.00075') ],
|
474
|
+
[ this.parseNumber ('20000'), this.parseNumber ('0.00065') ],
|
475
|
+
[ this.parseNumber ('40000'), this.parseNumber ('0.00065') ],
|
476
|
+
[ this.parseNumber ('75000'), this.parseNumber ('0.00065') ],
|
477
|
+
],
|
478
|
+
},
|
479
|
+
},
|
480
|
+
'swap': {
|
481
|
+
'tierBased': true,
|
482
|
+
'feeSide': 'base',
|
483
|
+
'percentage': true,
|
484
|
+
'maker': this.parseNumber ('0.0'),
|
485
|
+
'taker': this.parseNumber ('0.0005'),
|
486
|
+
'tiers': {
|
487
|
+
'maker': [
|
488
|
+
[ this.parseNumber ('0'), this.parseNumber ('0.0000') ],
|
489
|
+
[ this.parseNumber ('1.5'), this.parseNumber ('-0.00005') ],
|
490
|
+
[ this.parseNumber ('3'), this.parseNumber ('-0.00005') ],
|
491
|
+
[ this.parseNumber ('6'), this.parseNumber ('-0.00005') ],
|
492
|
+
[ this.parseNumber ('12.5'), this.parseNumber ('-0.00005') ],
|
493
|
+
[ this.parseNumber ('25'), this.parseNumber ('-0.00005') ],
|
494
|
+
[ this.parseNumber ('75'), this.parseNumber ('-0.00005') ],
|
495
|
+
[ this.parseNumber ('200'), this.parseNumber ('-0.00005') ],
|
496
|
+
[ this.parseNumber ('500'), this.parseNumber ('-0.00005') ],
|
497
|
+
[ this.parseNumber ('1250'), this.parseNumber ('-0.00005') ],
|
498
|
+
[ this.parseNumber ('2500'), this.parseNumber ('-0.00005') ],
|
499
|
+
[ this.parseNumber ('3000'), this.parseNumber ('-0.00008') ],
|
500
|
+
[ this.parseNumber ('6000'), this.parseNumber ('-0.01000') ],
|
501
|
+
[ this.parseNumber ('11000'), this.parseNumber ('-0.01002') ],
|
502
|
+
[ this.parseNumber ('20000'), this.parseNumber ('-0.01005') ],
|
503
|
+
[ this.parseNumber ('40000'), this.parseNumber ('-0.02000') ],
|
504
|
+
[ this.parseNumber ('75000'), this.parseNumber ('-0.02005') ],
|
505
|
+
],
|
506
|
+
'taker': [
|
507
|
+
[ this.parseNumber ('0'), this.parseNumber ('0.00050') ],
|
508
|
+
[ this.parseNumber ('1.5'), this.parseNumber ('0.00048') ],
|
509
|
+
[ this.parseNumber ('3'), this.parseNumber ('0.00046') ],
|
510
|
+
[ this.parseNumber ('6'), this.parseNumber ('0.00044') ],
|
511
|
+
[ this.parseNumber ('12.5'), this.parseNumber ('0.00042') ],
|
512
|
+
[ this.parseNumber ('25'), this.parseNumber ('0.00040') ],
|
513
|
+
[ this.parseNumber ('75'), this.parseNumber ('0.00038') ],
|
514
|
+
[ this.parseNumber ('200'), this.parseNumber ('0.00036') ],
|
515
|
+
[ this.parseNumber ('500'), this.parseNumber ('0.00034') ],
|
516
|
+
[ this.parseNumber ('1250'), this.parseNumber ('0.00032') ],
|
517
|
+
[ this.parseNumber ('2500'), this.parseNumber ('0.00030') ],
|
518
|
+
[ this.parseNumber ('3000'), this.parseNumber ('0.00030') ],
|
519
|
+
[ this.parseNumber ('6000'), this.parseNumber ('0.00030') ],
|
520
|
+
[ this.parseNumber ('11000'), this.parseNumber ('0.00030') ],
|
521
|
+
[ this.parseNumber ('20000'), this.parseNumber ('0.00030') ],
|
522
|
+
[ this.parseNumber ('40000'), this.parseNumber ('0.00030') ],
|
523
|
+
[ this.parseNumber ('75000'), this.parseNumber ('0.00030') ],
|
524
|
+
],
|
525
|
+
},
|
526
|
+
},
|
527
|
+
},
|
528
|
+
// https://www.gate.io/docs/apiv4/en/index.html#label-list
|
529
|
+
'exceptions': {
|
530
|
+
'exact': {
|
531
|
+
'INVALID_PARAM_VALUE': BadRequest,
|
532
|
+
'INVALID_PROTOCOL': BadRequest,
|
533
|
+
'INVALID_ARGUMENT': BadRequest,
|
534
|
+
'INVALID_REQUEST_BODY': BadRequest,
|
535
|
+
'MISSING_REQUIRED_PARAM': ArgumentsRequired,
|
536
|
+
'BAD_REQUEST': BadRequest,
|
537
|
+
'INVALID_CONTENT_TYPE': BadRequest,
|
538
|
+
'NOT_ACCEPTABLE': BadRequest,
|
539
|
+
'METHOD_NOT_ALLOWED': BadRequest,
|
540
|
+
'NOT_FOUND': ExchangeError,
|
541
|
+
'INVALID_CREDENTIALS': AuthenticationError,
|
542
|
+
'INVALID_KEY': AuthenticationError,
|
543
|
+
'IP_FORBIDDEN': AuthenticationError,
|
544
|
+
'READ_ONLY': PermissionDenied,
|
545
|
+
'INVALID_SIGNATURE': AuthenticationError,
|
546
|
+
'MISSING_REQUIRED_HEADER': AuthenticationError,
|
547
|
+
'REQUEST_EXPIRED': AuthenticationError,
|
548
|
+
'ACCOUNT_LOCKED': AccountSuspended,
|
549
|
+
'FORBIDDEN': PermissionDenied,
|
550
|
+
'SUB_ACCOUNT_NOT_FOUND': ExchangeError,
|
551
|
+
'SUB_ACCOUNT_LOCKED': AccountSuspended,
|
552
|
+
'MARGIN_BALANCE_EXCEPTION': ExchangeError,
|
553
|
+
'MARGIN_TRANSFER_FAILED': ExchangeError,
|
554
|
+
'TOO_MUCH_FUTURES_AVAILABLE': ExchangeError,
|
555
|
+
'FUTURES_BALANCE_NOT_ENOUGH': InsufficientFunds,
|
556
|
+
'ACCOUNT_EXCEPTION': ExchangeError,
|
557
|
+
'SUB_ACCOUNT_TRANSFER_FAILED': ExchangeError,
|
558
|
+
'ADDRESS_NOT_USED': ExchangeError,
|
559
|
+
'TOO_FAST': RateLimitExceeded,
|
560
|
+
'WITHDRAWAL_OVER_LIMIT': ExchangeError,
|
561
|
+
'API_WITHDRAW_DISABLED': ExchangeNotAvailable,
|
562
|
+
'INVALID_WITHDRAW_ID': ExchangeError,
|
563
|
+
'INVALID_WITHDRAW_CANCEL_STATUS': ExchangeError,
|
564
|
+
'INVALID_PRECISION': InvalidOrder,
|
565
|
+
'INVALID_CURRENCY': BadSymbol,
|
566
|
+
'INVALID_CURRENCY_PAIR': BadSymbol,
|
567
|
+
'POC_FILL_IMMEDIATELY': ExchangeError,
|
568
|
+
'ORDER_NOT_FOUND': OrderNotFound,
|
569
|
+
'CLIENT_ID_NOT_FOUND': OrderNotFound,
|
570
|
+
'ORDER_CLOSED': InvalidOrder,
|
571
|
+
'ORDER_CANCELLED': InvalidOrder,
|
572
|
+
'QUANTITY_NOT_ENOUGH': InvalidOrder,
|
573
|
+
'BALANCE_NOT_ENOUGH': InsufficientFunds,
|
574
|
+
'MARGIN_NOT_SUPPORTED': InvalidOrder,
|
575
|
+
'MARGIN_BALANCE_NOT_ENOUGH': InsufficientFunds,
|
576
|
+
'AMOUNT_TOO_LITTLE': InvalidOrder,
|
577
|
+
'AMOUNT_TOO_MUCH': InvalidOrder,
|
578
|
+
'REPEATED_CREATION': InvalidOrder,
|
579
|
+
'LOAN_NOT_FOUND': OrderNotFound,
|
580
|
+
'LOAN_RECORD_NOT_FOUND': OrderNotFound,
|
581
|
+
'NO_MATCHED_LOAN': ExchangeError,
|
582
|
+
'NOT_MERGEABLE': ExchangeError,
|
583
|
+
'NO_CHANGE': ExchangeError,
|
584
|
+
'REPAY_TOO_MUCH': ExchangeError,
|
585
|
+
'TOO_MANY_CURRENCY_PAIRS': InvalidOrder,
|
586
|
+
'TOO_MANY_ORDERS': InvalidOrder,
|
587
|
+
'MIXED_ACCOUNT_TYPE': InvalidOrder,
|
588
|
+
'AUTO_BORROW_TOO_MUCH': ExchangeError,
|
589
|
+
'TRADE_RESTRICTED': InsufficientFunds,
|
590
|
+
'USER_NOT_FOUND': AccountNotEnabled,
|
591
|
+
'CONTRACT_NO_COUNTER': ExchangeError,
|
592
|
+
'CONTRACT_NOT_FOUND': BadSymbol,
|
593
|
+
'RISK_LIMIT_EXCEEDED': ExchangeError,
|
594
|
+
'INSUFFICIENT_AVAILABLE': InsufficientFunds,
|
595
|
+
'LIQUIDATE_IMMEDIATELY': InvalidOrder,
|
596
|
+
'LEVERAGE_TOO_HIGH': InvalidOrder,
|
597
|
+
'LEVERAGE_TOO_LOW': InvalidOrder,
|
598
|
+
'ORDER_NOT_OWNED': ExchangeError,
|
599
|
+
'ORDER_FINISHED': ExchangeError,
|
600
|
+
'POSITION_CROSS_MARGIN': ExchangeError,
|
601
|
+
'POSITION_IN_LIQUIDATION': ExchangeError,
|
602
|
+
'POSITION_IN_CLOSE': ExchangeError,
|
603
|
+
'POSITION_EMPTY': InvalidOrder,
|
604
|
+
'REMOVE_TOO_MUCH': ExchangeError,
|
605
|
+
'RISK_LIMIT_NOT_MULTIPLE': ExchangeError,
|
606
|
+
'RISK_LIMIT_TOO_HIGH': ExchangeError,
|
607
|
+
'RISK_LIMIT_TOO_lOW': ExchangeError,
|
608
|
+
'PRICE_TOO_DEVIATED': InvalidOrder,
|
609
|
+
'SIZE_TOO_LARGE': InvalidOrder,
|
610
|
+
'SIZE_TOO_SMALL': InvalidOrder,
|
611
|
+
'PRICE_OVER_LIQUIDATION': InvalidOrder,
|
612
|
+
'PRICE_OVER_BANKRUPT': InvalidOrder,
|
613
|
+
'ORDER_POC_IMMEDIATE': InvalidOrder,
|
614
|
+
'INCREASE_POSITION': InvalidOrder,
|
615
|
+
'CONTRACT_IN_DELISTING': ExchangeError,
|
616
|
+
'INTERNAL': ExchangeNotAvailable,
|
617
|
+
'SERVER_ERROR': ExchangeNotAvailable,
|
618
|
+
'TOO_BUSY': ExchangeNotAvailable,
|
619
|
+
'CROSS_ACCOUNT_NOT_FOUND': ExchangeError,
|
620
|
+
},
|
621
|
+
},
|
622
|
+
'broad': {},
|
623
|
+
});
|
624
|
+
}
|
625
|
+
|
626
|
+
async fetchMarkets (params = {}) {
|
627
|
+
let result = [];
|
628
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('fetchMarkets', undefined, params);
|
629
|
+
if (type === 'spot' || type === 'margin') {
|
630
|
+
result = await this.fetchSpotMarkets (query);
|
631
|
+
}
|
632
|
+
if (type === 'swap' || type === 'future') {
|
633
|
+
result = await this.fetchContractMarkets (query); // futures and swaps
|
634
|
+
}
|
635
|
+
if (type === 'option') {
|
636
|
+
result = await this.fetchOptionMarkets (query);
|
637
|
+
}
|
638
|
+
const resultLength = result.length;
|
639
|
+
if (resultLength === 0) {
|
640
|
+
throw new ExchangeError (this.id + " does not support '" + type + "' type, set exchange.options['defaultType'] to " + "'spot', 'margin', 'swap', 'future' or 'option'"); // eslint-disable-line quotes
|
641
|
+
}
|
642
|
+
return result;
|
643
|
+
}
|
644
|
+
|
645
|
+
async fetchSpotMarkets (params) {
|
646
|
+
const marginResponse = await this.publicMarginGetCurrencyPairs (params);
|
647
|
+
const spotMarketsResponse = await this.publicSpotGetCurrencyPairs (params);
|
648
|
+
const marginMarkets = this.indexBy (marginResponse, 'id');
|
649
|
+
//
|
650
|
+
// Spot
|
651
|
+
//
|
652
|
+
// [
|
653
|
+
// {
|
654
|
+
// "id": "QTUM_ETH",
|
655
|
+
// "base": "QTUM",
|
656
|
+
// "quote": "ETH",
|
657
|
+
// "fee": "0.2",
|
658
|
+
// "min_base_amount": "0.01",
|
659
|
+
// "min_quote_amount": "0.001",
|
660
|
+
// "amount_precision": 3,
|
661
|
+
// "precision": 6,
|
662
|
+
// "trade_status": "tradable",
|
663
|
+
// "sell_start": 0,
|
664
|
+
// "buy_start": 0
|
665
|
+
// }
|
666
|
+
// ]
|
667
|
+
//
|
668
|
+
// Margin
|
669
|
+
//
|
670
|
+
// [
|
671
|
+
// {
|
672
|
+
// "id": "ETH_USDT",
|
673
|
+
// "base": "ETH",
|
674
|
+
// "quote": "USDT",
|
675
|
+
// "leverage": 3,
|
676
|
+
// "min_base_amount": "0.01",
|
677
|
+
// "min_quote_amount": "100",
|
678
|
+
// "max_quote_amount": "1000000"
|
679
|
+
// }
|
680
|
+
// ]
|
681
|
+
//
|
682
|
+
const result = [];
|
683
|
+
for (let i = 0; i < spotMarketsResponse.length; i++) {
|
684
|
+
const spotMarket = spotMarketsResponse[i];
|
685
|
+
const id = this.safeString (spotMarket, 'id');
|
686
|
+
const marginMarket = this.safeValue (marginMarkets, id);
|
687
|
+
const market = this.deepExtend (marginMarket, spotMarket);
|
688
|
+
const [ baseId, quoteId ] = id.split ('_');
|
689
|
+
const base = this.safeCurrencyCode (baseId);
|
690
|
+
const quote = this.safeCurrencyCode (quoteId);
|
691
|
+
const takerPercent = this.safeString (market, 'fee');
|
692
|
+
const makerPercent = this.safeString (market, 'maker_fee_rate', takerPercent);
|
693
|
+
const amountPrecisionString = this.safeString (market, 'amount_precision');
|
694
|
+
const pricePrecisionString = this.safeString (market, 'precision');
|
695
|
+
const tradeStatus = this.safeString (market, 'trade_status');
|
696
|
+
const leverage = this.safeNumber (market, 'leverage');
|
697
|
+
const defaultMinAmountLimit = this.parseNumber (this.parsePrecision (amountPrecisionString));
|
698
|
+
const margin = leverage !== undefined;
|
699
|
+
result.push ({
|
700
|
+
'id': id,
|
701
|
+
'symbol': base + '/' + quote,
|
702
|
+
'base': base,
|
703
|
+
'quote': quote,
|
704
|
+
'settle': undefined,
|
705
|
+
'baseId': baseId,
|
706
|
+
'quoteId': quoteId,
|
707
|
+
'settleId': undefined,
|
708
|
+
'type': 'spot',
|
709
|
+
'spot': true,
|
710
|
+
'margin': margin,
|
711
|
+
'swap': false,
|
712
|
+
'future': false,
|
713
|
+
'option': false,
|
714
|
+
'active': (tradeStatus === 'tradable'),
|
715
|
+
'contract': false,
|
716
|
+
'linear': undefined,
|
717
|
+
'inverse': undefined,
|
718
|
+
// Fee is in %, so divide by 100
|
719
|
+
'taker': this.parseNumber (Precise.stringDiv (takerPercent, '100')),
|
720
|
+
'maker': this.parseNumber (Precise.stringDiv (makerPercent, '100')),
|
721
|
+
'contractSize': undefined,
|
722
|
+
'expiry': undefined,
|
723
|
+
'expiryDatetime': undefined,
|
724
|
+
'strike': undefined,
|
725
|
+
'optionType': undefined,
|
726
|
+
'precision': {
|
727
|
+
'amount': this.parseNumber (this.parsePrecision (amountPrecisionString)),
|
728
|
+
'price': this.parseNumber (this.parsePrecision (pricePrecisionString)),
|
729
|
+
},
|
730
|
+
'limits': {
|
731
|
+
'leverage': {
|
732
|
+
'min': this.parseNumber ('1'),
|
733
|
+
'max': this.safeNumber (market, 'leverage', 1),
|
734
|
+
},
|
735
|
+
'amount': {
|
736
|
+
'min': this.safeNumber (spotMarket, 'min_base_amount', defaultMinAmountLimit),
|
737
|
+
'max': undefined,
|
738
|
+
},
|
739
|
+
'price': {
|
740
|
+
'min': undefined,
|
741
|
+
'max': undefined,
|
742
|
+
},
|
743
|
+
'cost': {
|
744
|
+
'min': this.safeNumber (market, 'min_quote_amount'),
|
745
|
+
'max': this.safeNumber (market, 'max_quote_amount'),
|
746
|
+
},
|
747
|
+
},
|
748
|
+
'info': market,
|
749
|
+
});
|
750
|
+
}
|
751
|
+
return result;
|
752
|
+
}
|
753
|
+
|
754
|
+
async fetchContractMarkets (params) {
|
755
|
+
const result = [];
|
756
|
+
const swapSettlementCurrencies = this.getSettlementCurrencies ('swap', 'fetchMarkets');
|
757
|
+
const futureSettlementCurrencies = this.getSettlementCurrencies ('future', 'fetchMarkets');
|
758
|
+
for (let c = 0; c < swapSettlementCurrencies.length; c++) {
|
759
|
+
const settleId = swapSettlementCurrencies[c];
|
760
|
+
const query = params;
|
761
|
+
query['settle'] = settleId;
|
762
|
+
const response = await this.publicFuturesGetSettleContracts (query);
|
763
|
+
for (let i = 0; i < response.length; i++) {
|
764
|
+
const parsedMarket = this.parseContractMarket (response[i], settleId);
|
765
|
+
result.push (parsedMarket);
|
766
|
+
}
|
767
|
+
}
|
768
|
+
for (let c = 0; c < futureSettlementCurrencies.length; c++) {
|
769
|
+
const settleId = futureSettlementCurrencies[c];
|
770
|
+
const query = params;
|
771
|
+
query['settle'] = settleId;
|
772
|
+
const response = await this.publicDeliveryGetSettleContracts (query);
|
773
|
+
for (let i = 0; i < response.length; i++) {
|
774
|
+
const parsedMarket = this.parseContractMarket (response[i], settleId);
|
775
|
+
result.push (parsedMarket);
|
776
|
+
}
|
777
|
+
}
|
778
|
+
return result;
|
779
|
+
}
|
780
|
+
|
781
|
+
parseContractMarket (market, settleId) {
|
782
|
+
//
|
783
|
+
// Perpetual swap
|
784
|
+
//
|
785
|
+
// {
|
786
|
+
// "name": "BTC_USDT",
|
787
|
+
// "type": "direct",
|
788
|
+
// "quanto_multiplier": "0.0001",
|
789
|
+
// "ref_discount_rate": "0",
|
790
|
+
// "order_price_deviate": "0.5",
|
791
|
+
// "maintenance_rate": "0.005",
|
792
|
+
// "mark_type": "index",
|
793
|
+
// "last_price": "38026",
|
794
|
+
// "mark_price": "37985.6",
|
795
|
+
// "index_price": "37954.92",
|
796
|
+
// "funding_rate_indicative": "0.000219",
|
797
|
+
// "mark_price_round": "0.01",
|
798
|
+
// "funding_offset": 0,
|
799
|
+
// "in_delisting": false,
|
800
|
+
// "risk_limit_base": "1000000",
|
801
|
+
// "interest_rate": "0.0003",
|
802
|
+
// "order_price_round": "0.1",
|
803
|
+
// "order_size_min": 1,
|
804
|
+
// "ref_rebate_rate": "0.2",
|
805
|
+
// "funding_interval": 28800,
|
806
|
+
// "risk_limit_step": "1000000",
|
807
|
+
// "leverage_min": "1",
|
808
|
+
// "leverage_max": "100",
|
809
|
+
// "risk_limit_max": "8000000",
|
810
|
+
// "maker_fee_rate": "-0.00025",
|
811
|
+
// "taker_fee_rate": "0.00075",
|
812
|
+
// "funding_rate": "0.002053",
|
813
|
+
// "order_size_max": 1000000,
|
814
|
+
// "funding_next_apply": 1610035200,
|
815
|
+
// "short_users": 977,
|
816
|
+
// "config_change_time": 1609899548,
|
817
|
+
// "trade_size": 28530850594,
|
818
|
+
// "position_size": 5223816,
|
819
|
+
// "long_users": 455,
|
820
|
+
// "funding_impact_value": "60000",
|
821
|
+
// "orders_limit": 50,
|
822
|
+
// "trade_id": 10851092,
|
823
|
+
// "orderbook_id": 2129638396
|
824
|
+
// }
|
825
|
+
//
|
826
|
+
// Delivery Futures
|
827
|
+
//
|
828
|
+
// {
|
829
|
+
// "name": "BTC_USDT_20200814",
|
830
|
+
// "underlying": "BTC_USDT",
|
831
|
+
// "cycle": "WEEKLY",
|
832
|
+
// "type": "direct",
|
833
|
+
// "quanto_multiplier": "0.0001",
|
834
|
+
// "mark_type": "index",
|
835
|
+
// "last_price": "9017",
|
836
|
+
// "mark_price": "9019",
|
837
|
+
// "index_price": "9005.3",
|
838
|
+
// "basis_rate": "0.185095",
|
839
|
+
// "basis_value": "13.7",
|
840
|
+
// "basis_impact_value": "100000",
|
841
|
+
// "settle_price": "0",
|
842
|
+
// "settle_price_interval": 60,
|
843
|
+
// "settle_price_duration": 1800,
|
844
|
+
// "settle_fee_rate": "0.0015",
|
845
|
+
// "expire_time": 1593763200,
|
846
|
+
// "order_price_round": "0.1",
|
847
|
+
// "mark_price_round": "0.1",
|
848
|
+
// "leverage_min": "1",
|
849
|
+
// "leverage_max": "100",
|
850
|
+
// "maintenance_rate": "1000000",
|
851
|
+
// "risk_limit_base": "140.726652109199",
|
852
|
+
// "risk_limit_step": "1000000",
|
853
|
+
// "risk_limit_max": "8000000",
|
854
|
+
// "maker_fee_rate": "-0.00025",
|
855
|
+
// "taker_fee_rate": "0.00075",
|
856
|
+
// "ref_discount_rate": "0",
|
857
|
+
// "ref_rebate_rate": "0.2",
|
858
|
+
// "order_price_deviate": "0.5",
|
859
|
+
// "order_size_min": 1,
|
860
|
+
// "order_size_max": 1000000,
|
861
|
+
// "orders_limit": 50,
|
862
|
+
// "orderbook_id": 63,
|
863
|
+
// "trade_id": 26,
|
864
|
+
// "trade_size": 435,
|
865
|
+
// "position_size": 130,
|
866
|
+
// "config_change_time": 1593158867,
|
867
|
+
// "in_delisting": false
|
868
|
+
// }
|
869
|
+
//
|
870
|
+
const id = this.safeString (market, 'name');
|
871
|
+
const parts = id.split ('_');
|
872
|
+
const baseId = this.safeString (parts, 0);
|
873
|
+
const quoteId = this.safeString (parts, 1);
|
874
|
+
const date = this.safeString (parts, 2);
|
875
|
+
const base = this.safeCurrencyCode (baseId);
|
876
|
+
const quote = this.safeCurrencyCode (quoteId);
|
877
|
+
const settle = this.safeCurrencyCode (settleId);
|
878
|
+
const expiry = this.safeTimestamp (market, 'expire_time');
|
879
|
+
let symbol = '';
|
880
|
+
let marketType = 'swap';
|
881
|
+
if (date !== undefined) {
|
882
|
+
symbol = base + '/' + quote + ':' + settle + '-' + this.yymmdd (expiry, '');
|
883
|
+
marketType = 'future';
|
884
|
+
} else {
|
885
|
+
symbol = base + '/' + quote + ':' + settle;
|
886
|
+
}
|
887
|
+
const priceDeviate = this.safeString (market, 'order_price_deviate');
|
888
|
+
const markPrice = this.safeString (market, 'mark_price');
|
889
|
+
const minMultiplier = Precise.stringSub ('1', priceDeviate);
|
890
|
+
const maxMultiplier = Precise.stringAdd ('1', priceDeviate);
|
891
|
+
const minPrice = Precise.stringMul (minMultiplier, markPrice);
|
892
|
+
const maxPrice = Precise.stringMul (maxMultiplier, markPrice);
|
893
|
+
const takerPercent = this.safeString (market, 'taker_fee_rate');
|
894
|
+
const makerPercent = this.safeString (market, 'maker_fee_rate', takerPercent);
|
895
|
+
const isLinear = quote === settle;
|
896
|
+
return {
|
897
|
+
'id': id,
|
898
|
+
'symbol': symbol,
|
899
|
+
'base': base,
|
900
|
+
'quote': quote,
|
901
|
+
'settle': settle,
|
902
|
+
'baseId': baseId,
|
903
|
+
'quoteId': quoteId,
|
904
|
+
'settleId': settleId,
|
905
|
+
'type': marketType,
|
906
|
+
'spot': false,
|
907
|
+
'margin': false,
|
908
|
+
'swap': marketType === 'swap',
|
909
|
+
'future': marketType === 'future',
|
910
|
+
'option': marketType === 'option',
|
911
|
+
'active': true,
|
912
|
+
'contract': true,
|
913
|
+
'linear': isLinear,
|
914
|
+
'inverse': !isLinear,
|
915
|
+
'taker': this.parseNumber (Precise.stringDiv (takerPercent, '100')), // Fee is in %, so divide by 100
|
916
|
+
'maker': this.parseNumber (Precise.stringDiv (makerPercent, '100')),
|
917
|
+
'contractSize': this.safeNumber (market, 'quanto_multiplier'),
|
918
|
+
'expiry': expiry,
|
919
|
+
'expiryDatetime': this.iso8601 (expiry),
|
920
|
+
'strike': undefined,
|
921
|
+
'optionType': undefined,
|
922
|
+
'precision': {
|
923
|
+
'amount': this.parseNumber ('1'),
|
924
|
+
'price': this.safeNumber (market, 'order_price_round'),
|
925
|
+
},
|
926
|
+
'limits': {
|
927
|
+
'leverage': {
|
928
|
+
'min': this.safeNumber (market, 'leverage_min'),
|
929
|
+
'max': this.safeNumber (market, 'leverage_max'),
|
930
|
+
},
|
931
|
+
'amount': {
|
932
|
+
'min': this.safeNumber (market, 'order_size_min'),
|
933
|
+
'max': this.safeNumber (market, 'order_size_max'),
|
934
|
+
},
|
935
|
+
'price': {
|
936
|
+
'min': this.parseNumber (minPrice),
|
937
|
+
'max': this.parseNumber (maxPrice),
|
938
|
+
},
|
939
|
+
'cost': {
|
940
|
+
'min': undefined,
|
941
|
+
'max': undefined,
|
942
|
+
},
|
943
|
+
},
|
944
|
+
'info': market,
|
945
|
+
};
|
946
|
+
}
|
947
|
+
|
948
|
+
async fetchOptionMarkets (params = {}) {
|
949
|
+
const result = [];
|
950
|
+
const underlyings = await this.fetchOptionUnderlyings ();
|
951
|
+
for (let i = 0; i < underlyings.length; i++) {
|
952
|
+
const underlying = underlyings[i];
|
953
|
+
const query = params;
|
954
|
+
query['underlying'] = underlying;
|
955
|
+
const response = await this.publicOptionsGetContracts (query);
|
956
|
+
//
|
957
|
+
// [
|
958
|
+
// {
|
959
|
+
// "orders_limit": "50",
|
960
|
+
// "order_size_max": "100000",
|
961
|
+
// "mark_price_round": "0.1",
|
962
|
+
// "order_size_min": "1",
|
963
|
+
// "position_limit": "1000000",
|
964
|
+
// "orderbook_id": "575967",
|
965
|
+
// "order_price_deviate": "0.9",
|
966
|
+
// "is_call": true, // true means Call false means Put
|
967
|
+
// "last_price": "93.9",
|
968
|
+
// "bid1_size": "0",
|
969
|
+
// "bid1_price": "0",
|
970
|
+
// "taker_fee_rate": "0.0004",
|
971
|
+
// "underlying": "BTC_USDT",
|
972
|
+
// "create_time": "1646381188",
|
973
|
+
// "price_limit_fee_rate": "0.1",
|
974
|
+
// "maker_fee_rate": "0.0004",
|
975
|
+
// "trade_id": "727",
|
976
|
+
// "order_price_round": "0.1",
|
977
|
+
// "settle_fee_rate": "0.0001",
|
978
|
+
// "trade_size": "1982",
|
979
|
+
// "ref_rebate_rate": "0",
|
980
|
+
// "name": "BTC_USDT-20220311-44000-C",
|
981
|
+
// "underlying_price": "39194.26",
|
982
|
+
// "strike_price": "44000",
|
983
|
+
// "multiplier": "0.0001",
|
984
|
+
// "ask1_price": "0",
|
985
|
+
// "ref_discount_rate": "0",
|
986
|
+
// "expiration_time": "1646985600",
|
987
|
+
// "mark_price": "12.15",
|
988
|
+
// "position_size": "4",
|
989
|
+
// "ask1_size": "0",
|
990
|
+
// "tag": "WEEK"
|
991
|
+
// }
|
992
|
+
// ]
|
993
|
+
//
|
994
|
+
for (let i = 0; i < response.length; i++) {
|
995
|
+
const market = response[i];
|
996
|
+
const id = this.safeString (market, 'name');
|
997
|
+
const parts = underlying.split ('_');
|
998
|
+
const baseId = this.safeString (parts, 0);
|
999
|
+
const quoteId = this.safeString (parts, 1);
|
1000
|
+
const base = this.safeCurrencyCode (baseId);
|
1001
|
+
const quote = this.safeCurrencyCode (quoteId);
|
1002
|
+
let symbol = base + '/' + quote;
|
1003
|
+
const expiry = this.safeTimestamp (market, 'expiration_time');
|
1004
|
+
const strike = this.safeString (market, 'strike_price');
|
1005
|
+
const isCall = this.safeValue (market, 'is_call');
|
1006
|
+
const optionLetter = isCall ? 'C' : 'P';
|
1007
|
+
const optionType = isCall ? 'call' : 'put';
|
1008
|
+
symbol = symbol + ':' + quote + '-' + this.yymmdd (expiry) + ':' + strike + ':' + optionLetter;
|
1009
|
+
const priceDeviate = this.safeString (market, 'order_price_deviate');
|
1010
|
+
const markPrice = this.safeString (market, 'mark_price');
|
1011
|
+
const minMultiplier = Precise.stringSub ('1', priceDeviate);
|
1012
|
+
const maxMultiplier = Precise.stringAdd ('1', priceDeviate);
|
1013
|
+
const minPrice = Precise.stringMul (minMultiplier, markPrice);
|
1014
|
+
const maxPrice = Precise.stringMul (maxMultiplier, markPrice);
|
1015
|
+
const takerPercent = this.safeString (market, 'taker_fee_rate');
|
1016
|
+
const makerPercent = this.safeString (market, 'maker_fee_rate', takerPercent);
|
1017
|
+
result.push ({
|
1018
|
+
'id': id,
|
1019
|
+
'symbol': symbol,
|
1020
|
+
'base': base,
|
1021
|
+
'quote': quote,
|
1022
|
+
'settle': quote,
|
1023
|
+
'baseId': baseId,
|
1024
|
+
'quoteId': quoteId,
|
1025
|
+
'settleId': quoteId,
|
1026
|
+
'type': 'option',
|
1027
|
+
'spot': false,
|
1028
|
+
'margin': false,
|
1029
|
+
'swap': false,
|
1030
|
+
'future': false,
|
1031
|
+
'option': true,
|
1032
|
+
'active': true,
|
1033
|
+
'contract': true,
|
1034
|
+
'linear': true,
|
1035
|
+
'inverse': false,
|
1036
|
+
'taker': this.parseNumber (Precise.stringDiv (takerPercent, '100')), // Fee is in %, so divide by 100
|
1037
|
+
'maker': this.parseNumber (Precise.stringDiv (makerPercent, '100')),
|
1038
|
+
'contractSize': this.parseNumber ('1'),
|
1039
|
+
'expiry': expiry,
|
1040
|
+
'expiryDatetime': this.iso8601 (expiry),
|
1041
|
+
'strike': strike,
|
1042
|
+
'optionType': optionType,
|
1043
|
+
'precision': {
|
1044
|
+
'amount': this.parseNumber ('1'),
|
1045
|
+
'price': this.safeNumber (market, 'order_price_round'),
|
1046
|
+
},
|
1047
|
+
'limits': {
|
1048
|
+
'leverage': {
|
1049
|
+
'min': undefined,
|
1050
|
+
'max': undefined,
|
1051
|
+
},
|
1052
|
+
'amount': {
|
1053
|
+
'min': this.safeNumber (market, 'order_size_min'),
|
1054
|
+
'max': this.safeNumber (market, 'order_size_max'),
|
1055
|
+
},
|
1056
|
+
'price': {
|
1057
|
+
'min': this.parseNumber (minPrice),
|
1058
|
+
'max': this.parseNumber (maxPrice),
|
1059
|
+
},
|
1060
|
+
'cost': {
|
1061
|
+
'min': undefined,
|
1062
|
+
'max': undefined,
|
1063
|
+
},
|
1064
|
+
},
|
1065
|
+
'info': market,
|
1066
|
+
});
|
1067
|
+
}
|
1068
|
+
}
|
1069
|
+
return result;
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
async fetchOptionUnderlyings () {
|
1073
|
+
const underlyingsResponse = await this.publicOptionsGetUnderlyings ();
|
1074
|
+
//
|
1075
|
+
// [
|
1076
|
+
// {
|
1077
|
+
// "index_time": "1646915796",
|
1078
|
+
// "name": "BTC_USDT",
|
1079
|
+
// "index_price": "39142.73"
|
1080
|
+
// }
|
1081
|
+
// ]
|
1082
|
+
//
|
1083
|
+
const underlyings = [];
|
1084
|
+
for (let i = 0; i < underlyingsResponse.length; i++) {
|
1085
|
+
const underlying = underlyingsResponse[i];
|
1086
|
+
const name = this.safeString (underlying, 'name');
|
1087
|
+
if (name !== undefined) {
|
1088
|
+
underlyings.push (name);
|
1089
|
+
}
|
1090
|
+
}
|
1091
|
+
return underlyings;
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
prepareRequest (market) {
|
1095
|
+
if (market !== undefined) {
|
1096
|
+
if (market['contract']) {
|
1097
|
+
return {
|
1098
|
+
'contract': market['id'],
|
1099
|
+
'settle': market['settleId'],
|
1100
|
+
};
|
1101
|
+
} else {
|
1102
|
+
return {
|
1103
|
+
'currency_pair': market['id'],
|
1104
|
+
};
|
1105
|
+
}
|
1106
|
+
}
|
1107
|
+
}
|
1108
|
+
|
1109
|
+
getMarginType (stop, params) {
|
1110
|
+
/**
|
1111
|
+
* @ignore
|
1112
|
+
* @method
|
1113
|
+
* @name gateio#getMarginType
|
1114
|
+
* @description Gets the margin type for this api call
|
1115
|
+
* @param {bool} stop True if for a stop order
|
1116
|
+
* @param {dict} params Request params
|
1117
|
+
* @returns The marginType and the updated request params with marginType removed, marginType value is the value that can be read by the "account" property specified in gateios api docs
|
1118
|
+
*/
|
1119
|
+
const defaultMarginType = this.safeStringLower2 (this.options, 'defaultMarginType', 'marginType', 'spot'); // 'margin' is isolated margin on gateio's api
|
1120
|
+
let marginType = this.safeStringLower2 (params, 'marginType', 'account', defaultMarginType);
|
1121
|
+
params = this.omit (params, [ 'marginType' ]);
|
1122
|
+
if (marginType === 'cross') {
|
1123
|
+
marginType = 'cross_margin';
|
1124
|
+
} else if (marginType === 'isolated') {
|
1125
|
+
marginType = 'margin';
|
1126
|
+
} else if (marginType === '') {
|
1127
|
+
marginType = 'spot';
|
1128
|
+
}
|
1129
|
+
if (stop) {
|
1130
|
+
if (marginType === 'spot') {
|
1131
|
+
marginType = 'normal';
|
1132
|
+
// gateio spot and margin stop orders use the term normal instead of spot
|
1133
|
+
}
|
1134
|
+
if (marginType === 'cross_margin') {
|
1135
|
+
throw new BadRequest (this.id + ' getMarginType() does not support stop orders for cross margin');
|
1136
|
+
}
|
1137
|
+
}
|
1138
|
+
return [ marginType, params ];
|
1139
|
+
}
|
1140
|
+
|
1141
|
+
getSettlementCurrencies (type, method) {
|
1142
|
+
const options = this.safeValue (this.options, type, {}); // [ 'BTC', 'USDT' ] unified codes
|
1143
|
+
const fetchMarketsContractOptions = this.safeValue (options, method, {});
|
1144
|
+
const defaultSettle = (type === 'swap') ? [ 'usdt' ] : [ 'btc' ];
|
1145
|
+
return this.safeValue (fetchMarketsContractOptions, 'settlementCurrencies', defaultSettle);
|
1146
|
+
}
|
1147
|
+
|
1148
|
+
async fetchCurrencies (params = {}) {
|
1149
|
+
// sandbox/testnet only supports future markets
|
1150
|
+
const apiBackup = this.safeValue (this.urls, 'apiBackup');
|
1151
|
+
if (apiBackup !== undefined) {
|
1152
|
+
return undefined;
|
1153
|
+
}
|
1154
|
+
const response = await this.publicSpotGetCurrencies (params);
|
1155
|
+
//
|
1156
|
+
// {
|
1157
|
+
// "currency": "BCN",
|
1158
|
+
// "delisted": false,
|
1159
|
+
// "withdraw_disabled": true,
|
1160
|
+
// "withdraw_delayed": false,
|
1161
|
+
// "deposit_disabled": true,
|
1162
|
+
// "trade_disabled": false
|
1163
|
+
// }
|
1164
|
+
//
|
1165
|
+
const result = {};
|
1166
|
+
// TODO: remove magic constants
|
1167
|
+
const amountPrecision = this.parseNumber ('1e-6');
|
1168
|
+
for (let i = 0; i < response.length; i++) {
|
1169
|
+
const entry = response[i];
|
1170
|
+
const currencyId = this.safeString (entry, 'currency');
|
1171
|
+
const currencyIdLower = this.safeStringLower (entry, 'currency');
|
1172
|
+
const code = this.safeCurrencyCode (currencyId);
|
1173
|
+
const delisted = this.safeValue (entry, 'delisted');
|
1174
|
+
const withdrawDisabled = this.safeValue (entry, 'withdraw_disabled', false);
|
1175
|
+
const depositDisabled = this.safeValue (entry, 'deposit_disabled', false);
|
1176
|
+
const tradeDisabled = this.safeValue (entry, 'trade_disabled', false);
|
1177
|
+
const withdrawEnabled = !withdrawDisabled;
|
1178
|
+
const depositEnabled = !depositDisabled;
|
1179
|
+
const tradeEnabled = !tradeDisabled;
|
1180
|
+
const listed = !delisted;
|
1181
|
+
const active = listed && tradeEnabled && withdrawEnabled && depositEnabled;
|
1182
|
+
result[code] = {
|
1183
|
+
'id': currencyId,
|
1184
|
+
'lowerCaseId': currencyIdLower,
|
1185
|
+
'name': undefined,
|
1186
|
+
'code': code,
|
1187
|
+
'precision': amountPrecision,
|
1188
|
+
'info': entry,
|
1189
|
+
'active': active,
|
1190
|
+
'deposit': depositEnabled,
|
1191
|
+
'withdraw': withdrawEnabled,
|
1192
|
+
'fee': undefined,
|
1193
|
+
'fees': [],
|
1194
|
+
'limits': this.limits,
|
1195
|
+
};
|
1196
|
+
}
|
1197
|
+
return result;
|
1198
|
+
}
|
1199
|
+
|
1200
|
+
async fetchFundingRate (symbol, params = {}) {
|
1201
|
+
await this.loadMarkets ();
|
1202
|
+
const market = this.market (symbol);
|
1203
|
+
if (!market['swap']) {
|
1204
|
+
throw new BadRequest ('Funding rates only exist for swap contracts');
|
1205
|
+
}
|
1206
|
+
const request = this.prepareRequest (market);
|
1207
|
+
const response = await this.publicFuturesGetSettleContractsContract (this.extend (request, params));
|
1208
|
+
//
|
1209
|
+
// [
|
1210
|
+
// {
|
1211
|
+
// "name": "BTC_USDT",
|
1212
|
+
// "type": "direct",
|
1213
|
+
// "quanto_multiplier": "0.0001",
|
1214
|
+
// "ref_discount_rate": "0",
|
1215
|
+
// "order_price_deviate": "0.5",
|
1216
|
+
// "maintenance_rate": "0.005",
|
1217
|
+
// "mark_type": "index",
|
1218
|
+
// "last_price": "38026",
|
1219
|
+
// "mark_price": "37985.6",
|
1220
|
+
// "index_price": "37954.92",
|
1221
|
+
// "funding_rate_indicative": "0.000219",
|
1222
|
+
// "mark_price_round": "0.01",
|
1223
|
+
// "funding_offset": 0,
|
1224
|
+
// "in_delisting": false,
|
1225
|
+
// "risk_limit_base": "1000000",
|
1226
|
+
// "interest_rate": "0.0003",
|
1227
|
+
// "order_price_round": "0.1",
|
1228
|
+
// "order_size_min": 1,
|
1229
|
+
// "ref_rebate_rate": "0.2",
|
1230
|
+
// "funding_interval": 28800,
|
1231
|
+
// "risk_limit_step": "1000000",
|
1232
|
+
// "leverage_min": "1",
|
1233
|
+
// "leverage_max": "100",
|
1234
|
+
// "risk_limit_max": "8000000",
|
1235
|
+
// "maker_fee_rate": "-0.00025",
|
1236
|
+
// "taker_fee_rate": "0.00075",
|
1237
|
+
// "funding_rate": "0.002053",
|
1238
|
+
// "order_size_max": 1000000,
|
1239
|
+
// "funding_next_apply": 1610035200,
|
1240
|
+
// "short_users": 977,
|
1241
|
+
// "config_change_time": 1609899548,
|
1242
|
+
// "trade_size": 28530850594,
|
1243
|
+
// "position_size": 5223816,
|
1244
|
+
// "long_users": 455,
|
1245
|
+
// "funding_impact_value": "60000",
|
1246
|
+
// "orders_limit": 50,
|
1247
|
+
// "trade_id": 10851092,
|
1248
|
+
// "orderbook_id": 2129638396
|
1249
|
+
// }
|
1250
|
+
// ]
|
1251
|
+
//
|
1252
|
+
return this.parseFundingRate (response);
|
1253
|
+
}
|
1254
|
+
|
1255
|
+
async fetchFundingRates (symbols = undefined, params = {}) {
|
1256
|
+
await this.loadMarkets ();
|
1257
|
+
const settle = this.safeStringLower (params, 'settle');
|
1258
|
+
const request = {
|
1259
|
+
'settle': settle,
|
1260
|
+
};
|
1261
|
+
const response = await this.publicFuturesGetSettleContracts (this.extend (request, params));
|
1262
|
+
//
|
1263
|
+
// [
|
1264
|
+
// {
|
1265
|
+
// "name": "BTC_USDT",
|
1266
|
+
// "type": "direct",
|
1267
|
+
// "quanto_multiplier": "0.0001",
|
1268
|
+
// "ref_discount_rate": "0",
|
1269
|
+
// "order_price_deviate": "0.5",
|
1270
|
+
// "maintenance_rate": "0.005",
|
1271
|
+
// "mark_type": "index",
|
1272
|
+
// "last_price": "38026",
|
1273
|
+
// "mark_price": "37985.6",
|
1274
|
+
// "index_price": "37954.92",
|
1275
|
+
// "funding_rate_indicative": "0.000219",
|
1276
|
+
// "mark_price_round": "0.01",
|
1277
|
+
// "funding_offset": 0,
|
1278
|
+
// "in_delisting": false,
|
1279
|
+
// "risk_limit_base": "1000000",
|
1280
|
+
// "interest_rate": "0.0003",
|
1281
|
+
// "order_price_round": "0.1",
|
1282
|
+
// "order_size_min": 1,
|
1283
|
+
// "ref_rebate_rate": "0.2",
|
1284
|
+
// "funding_interval": 28800,
|
1285
|
+
// "risk_limit_step": "1000000",
|
1286
|
+
// "leverage_min": "1",
|
1287
|
+
// "leverage_max": "100",
|
1288
|
+
// "risk_limit_max": "8000000",
|
1289
|
+
// "maker_fee_rate": "-0.00025",
|
1290
|
+
// "taker_fee_rate": "0.00075",
|
1291
|
+
// "funding_rate": "0.002053",
|
1292
|
+
// "order_size_max": 1000000,
|
1293
|
+
// "funding_next_apply": 1610035200,
|
1294
|
+
// "short_users": 977,
|
1295
|
+
// "config_change_time": 1609899548,
|
1296
|
+
// "trade_size": 28530850594,
|
1297
|
+
// "position_size": 5223816,
|
1298
|
+
// "long_users": 455,
|
1299
|
+
// "funding_impact_value": "60000",
|
1300
|
+
// "orders_limit": 50,
|
1301
|
+
// "trade_id": 10851092,
|
1302
|
+
// "orderbook_id": 2129638396
|
1303
|
+
// }
|
1304
|
+
// ]
|
1305
|
+
//
|
1306
|
+
const result = this.parseFundingRates (response);
|
1307
|
+
return this.filterByArray (result, 'symbol', symbols);
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
parseFundingRate (contract, market = undefined) {
|
1311
|
+
//
|
1312
|
+
// {
|
1313
|
+
// "name": "BTC_USDT",
|
1314
|
+
// "type": "direct",
|
1315
|
+
// "quanto_multiplier": "0.0001",
|
1316
|
+
// "ref_discount_rate": "0",
|
1317
|
+
// "order_price_deviate": "0.5",
|
1318
|
+
// "maintenance_rate": "0.005",
|
1319
|
+
// "mark_type": "index",
|
1320
|
+
// "last_price": "38026",
|
1321
|
+
// "mark_price": "37985.6",
|
1322
|
+
// "index_price": "37954.92",
|
1323
|
+
// "funding_rate_indicative": "0.000219",
|
1324
|
+
// "mark_price_round": "0.01",
|
1325
|
+
// "funding_offset": 0,
|
1326
|
+
// "in_delisting": false,
|
1327
|
+
// "risk_limit_base": "1000000",
|
1328
|
+
// "interest_rate": "0.0003",
|
1329
|
+
// "order_price_round": "0.1",
|
1330
|
+
// "order_size_min": 1,
|
1331
|
+
// "ref_rebate_rate": "0.2",
|
1332
|
+
// "funding_interval": 28800,
|
1333
|
+
// "risk_limit_step": "1000000",
|
1334
|
+
// "leverage_min": "1",
|
1335
|
+
// "leverage_max": "100",
|
1336
|
+
// "risk_limit_max": "8000000",
|
1337
|
+
// "maker_fee_rate": "-0.00025",
|
1338
|
+
// "taker_fee_rate": "0.00075",
|
1339
|
+
// "funding_rate": "0.002053",
|
1340
|
+
// "order_size_max": 1000000,
|
1341
|
+
// "funding_next_apply": 1610035200,
|
1342
|
+
// "short_users": 977,
|
1343
|
+
// "config_change_time": 1609899548,
|
1344
|
+
// "trade_size": 28530850594,
|
1345
|
+
// "position_size": 5223816,
|
1346
|
+
// "long_users": 455,
|
1347
|
+
// "funding_impact_value": "60000",
|
1348
|
+
// "orders_limit": 50,
|
1349
|
+
// "trade_id": 10851092,
|
1350
|
+
// "orderbook_id": 2129638396
|
1351
|
+
// }
|
1352
|
+
//
|
1353
|
+
const marketId = this.safeString (contract, 'name');
|
1354
|
+
const symbol = this.safeSymbol (marketId, market);
|
1355
|
+
const markPrice = this.safeNumber (contract, 'mark_price');
|
1356
|
+
const indexPrice = this.safeNumber (contract, 'index_price');
|
1357
|
+
const interestRate = this.safeNumber (contract, 'interest_rate');
|
1358
|
+
const fundingRate = this.safeNumber (contract, 'funding_rate');
|
1359
|
+
const fundingTime = this.safeInteger (contract, 'funding_next_apply') * 1000;
|
1360
|
+
const fundingRateIndicative = this.safeNumber (contract, 'funding_rate_indicative');
|
1361
|
+
return {
|
1362
|
+
'info': contract,
|
1363
|
+
'symbol': symbol,
|
1364
|
+
'markPrice': markPrice,
|
1365
|
+
'indexPrice': indexPrice,
|
1366
|
+
'interestRate': interestRate,
|
1367
|
+
'estimatedSettlePrice': undefined,
|
1368
|
+
'timestamp': undefined,
|
1369
|
+
'datetime': undefined,
|
1370
|
+
'fundingRate': fundingRate,
|
1371
|
+
'fundingTimestamp': fundingTime,
|
1372
|
+
'fundingDatetime': this.iso8601 (fundingTime),
|
1373
|
+
'nextFundingRate': fundingRateIndicative,
|
1374
|
+
'nextFundingTimestamp': undefined,
|
1375
|
+
'nextFundingDatetime': undefined,
|
1376
|
+
'previousFundingRate': undefined,
|
1377
|
+
'previousFundingTimestamp': undefined,
|
1378
|
+
'previousFundingDatetime': undefined,
|
1379
|
+
};
|
1380
|
+
}
|
1381
|
+
|
1382
|
+
async fetchNetworkDepositAddress (code, params = {}) {
|
1383
|
+
await this.loadMarkets ();
|
1384
|
+
const currency = this.currency (code);
|
1385
|
+
const request = {
|
1386
|
+
'currency': currency['id'],
|
1387
|
+
};
|
1388
|
+
const response = await this.privateWalletGetDepositAddress (this.extend (request, params));
|
1389
|
+
const addresses = this.safeValue (response, 'multichain_addresses');
|
1390
|
+
const currencyId = this.safeString (response, 'currency');
|
1391
|
+
code = this.safeCurrencyCode (currencyId);
|
1392
|
+
const result = {};
|
1393
|
+
for (let i = 0; i < addresses.length; i++) {
|
1394
|
+
const entry = addresses[i];
|
1395
|
+
//
|
1396
|
+
// {
|
1397
|
+
// "chain": "ETH",
|
1398
|
+
// "address": "0x359a697945E79C7e17b634675BD73B33324E9408",
|
1399
|
+
// "payment_id": "",
|
1400
|
+
// "payment_name": "",
|
1401
|
+
// "obtain_failed": "0"
|
1402
|
+
// }
|
1403
|
+
//
|
1404
|
+
const obtainFailed = this.safeInteger (entry, 'obtain_failed');
|
1405
|
+
if (obtainFailed) {
|
1406
|
+
continue;
|
1407
|
+
}
|
1408
|
+
const network = this.safeString (entry, 'chain');
|
1409
|
+
const address = this.safeString (entry, 'address');
|
1410
|
+
let tag = this.safeString (entry, 'payment_id');
|
1411
|
+
const tagLength = tag.length;
|
1412
|
+
tag = tagLength ? tag : undefined;
|
1413
|
+
result[network] = {
|
1414
|
+
'info': entry,
|
1415
|
+
'code': code,
|
1416
|
+
'address': address,
|
1417
|
+
'tag': tag,
|
1418
|
+
};
|
1419
|
+
}
|
1420
|
+
return result;
|
1421
|
+
}
|
1422
|
+
|
1423
|
+
async fetchDepositAddress (code, params = {}) {
|
1424
|
+
await this.loadMarkets ();
|
1425
|
+
const currency = this.currency (code);
|
1426
|
+
const request = {
|
1427
|
+
'currency': currency['id'],
|
1428
|
+
};
|
1429
|
+
const response = await this.privateWalletGetDepositAddress (this.extend (request, params));
|
1430
|
+
//
|
1431
|
+
// {
|
1432
|
+
// "currency": "XRP",
|
1433
|
+
// "address": "rHcFoo6a9qT5NHiVn1THQRhsEGcxtYCV4d 391331007",
|
1434
|
+
// "multichain_addresses": [
|
1435
|
+
// {
|
1436
|
+
// "chain": "XRP",
|
1437
|
+
// "address": "rHcFoo6a9qT5NHiVn1THQRhsEGcxtYCV4d",
|
1438
|
+
// "payment_id": "391331007",
|
1439
|
+
// "payment_name": "Tag",
|
1440
|
+
// "obtain_failed": 0
|
1441
|
+
// }
|
1442
|
+
// ]
|
1443
|
+
// }
|
1444
|
+
//
|
1445
|
+
const currencyId = this.safeString (response, 'currency');
|
1446
|
+
code = this.safeCurrencyCode (currencyId);
|
1447
|
+
const addressField = this.safeString (response, 'address');
|
1448
|
+
let tag = undefined;
|
1449
|
+
let address = undefined;
|
1450
|
+
if (addressField.indexOf (' ') >= 0) {
|
1451
|
+
const splitted = addressField.split (' ');
|
1452
|
+
address = splitted[0];
|
1453
|
+
tag = splitted[1];
|
1454
|
+
} else {
|
1455
|
+
address = addressField;
|
1456
|
+
}
|
1457
|
+
return {
|
1458
|
+
'info': response,
|
1459
|
+
'code': code,
|
1460
|
+
'address': address,
|
1461
|
+
'tag': tag,
|
1462
|
+
'network': undefined,
|
1463
|
+
};
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
async fetchTradingFee (symbol, params = {}) {
|
1467
|
+
await this.loadMarkets ();
|
1468
|
+
const market = this.market (symbol);
|
1469
|
+
const request = {
|
1470
|
+
'currency_pair': market['id'],
|
1471
|
+
};
|
1472
|
+
const response = await this.privateWalletGetFee (this.extend (request, params));
|
1473
|
+
//
|
1474
|
+
// {
|
1475
|
+
// "user_id": 1486602,
|
1476
|
+
// "taker_fee": "0.002",
|
1477
|
+
// "maker_fee": "0.002",
|
1478
|
+
// "gt_discount": true,
|
1479
|
+
// "gt_taker_fee": "0.0015",
|
1480
|
+
// "gt_maker_fee": "0.0015",
|
1481
|
+
// "loan_fee": "0.18",
|
1482
|
+
// "point_type": "0",
|
1483
|
+
// "futures_taker_fee": "0.0005",
|
1484
|
+
// "futures_maker_fee": "0"
|
1485
|
+
// }
|
1486
|
+
//
|
1487
|
+
return this.parseTradingFee (response, market);
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
async fetchTradingFees (params = {}) {
|
1491
|
+
await this.loadMarkets ();
|
1492
|
+
const response = await this.privateWalletGetFee (params);
|
1493
|
+
//
|
1494
|
+
// {
|
1495
|
+
// "user_id": 1486602,
|
1496
|
+
// "taker_fee": "0.002",
|
1497
|
+
// "maker_fee": "0.002",
|
1498
|
+
// "gt_discount": true,
|
1499
|
+
// "gt_taker_fee": "0.0015",
|
1500
|
+
// "gt_maker_fee": "0.0015",
|
1501
|
+
// "loan_fee": "0.18",
|
1502
|
+
// "point_type": "0",
|
1503
|
+
// "futures_taker_fee": "0.0005",
|
1504
|
+
// "futures_maker_fee": "0"
|
1505
|
+
// }
|
1506
|
+
//
|
1507
|
+
return this.parseTradingFees (response);
|
1508
|
+
}
|
1509
|
+
|
1510
|
+
parseTradingFees (response) {
|
1511
|
+
const result = {};
|
1512
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
1513
|
+
const symbol = this.symbols[i];
|
1514
|
+
const market = this.market (symbol);
|
1515
|
+
result[symbol] = this.parseTradingFee (response, market);
|
1516
|
+
}
|
1517
|
+
return result;
|
1518
|
+
}
|
1519
|
+
|
1520
|
+
parseTradingFee (info, market = undefined) {
|
1521
|
+
//
|
1522
|
+
// {
|
1523
|
+
// "user_id": 1486602,
|
1524
|
+
// "taker_fee": "0.002",
|
1525
|
+
// "maker_fee": "0.002",
|
1526
|
+
// "gt_discount": true,
|
1527
|
+
// "gt_taker_fee": "0.0015",
|
1528
|
+
// "gt_maker_fee": "0.0015",
|
1529
|
+
// "loan_fee": "0.18",
|
1530
|
+
// "point_type": "0",
|
1531
|
+
// "futures_taker_fee": "0.0005",
|
1532
|
+
// "futures_maker_fee": "0"
|
1533
|
+
// }
|
1534
|
+
//
|
1535
|
+
const contract = this.safeValue (market, 'contract');
|
1536
|
+
const takerKey = contract ? 'futures_taker_fee' : 'taker_fee';
|
1537
|
+
const makerKey = contract ? 'futures_maker_fee' : 'maker_fee';
|
1538
|
+
return {
|
1539
|
+
'info': info,
|
1540
|
+
'symbol': this.safeString (market, 'symbol'),
|
1541
|
+
'maker': this.safeNumber (info, makerKey),
|
1542
|
+
'taker': this.safeNumber (info, takerKey),
|
1543
|
+
};
|
1544
|
+
}
|
1545
|
+
|
1546
|
+
async fetchFundingFees (params = {}) {
|
1547
|
+
await this.loadMarkets ();
|
1548
|
+
const response = await this.privateWalletGetWithdrawStatus (params);
|
1549
|
+
//
|
1550
|
+
// {
|
1551
|
+
// "currency": "MTN",
|
1552
|
+
// "name": "Medicalchain",
|
1553
|
+
// "name_cn": "Medicalchain",
|
1554
|
+
// "deposit": "0",
|
1555
|
+
// "withdraw_percent": "0%",
|
1556
|
+
// "withdraw_fix": "900",
|
1557
|
+
// "withdraw_day_limit": "500000",
|
1558
|
+
// "withdraw_day_limit_remain": "500000",
|
1559
|
+
// "withdraw_amount_mini": "900.1",
|
1560
|
+
// "withdraw_eachtime_limit": "90000000000",
|
1561
|
+
// "withdraw_fix_on_chains": {
|
1562
|
+
// "ETH": "900"
|
1563
|
+
// }
|
1564
|
+
// }
|
1565
|
+
//
|
1566
|
+
const withdrawFees = {};
|
1567
|
+
for (let i = 0; i < response.length; i++) {
|
1568
|
+
const entry = response[i];
|
1569
|
+
const currencyId = this.safeString (entry, 'currency');
|
1570
|
+
const code = this.safeCurrencyCode (currencyId);
|
1571
|
+
withdrawFees[code] = {};
|
1572
|
+
let withdrawFix = this.safeValue (entry, 'withdraw_fix_on_chains');
|
1573
|
+
if (withdrawFix === undefined) {
|
1574
|
+
withdrawFix = {};
|
1575
|
+
withdrawFix[code] = this.safeNumber (entry, 'withdraw_fix');
|
1576
|
+
}
|
1577
|
+
const keys = Object.keys (withdrawFix);
|
1578
|
+
for (let i = 0; i < keys.length; i++) {
|
1579
|
+
const key = keys[i];
|
1580
|
+
withdrawFees[code][key] = this.parseNumber (withdrawFix[key]);
|
1581
|
+
}
|
1582
|
+
}
|
1583
|
+
return {
|
1584
|
+
'info': response,
|
1585
|
+
'withdraw': withdrawFees,
|
1586
|
+
'deposit': {},
|
1587
|
+
};
|
1588
|
+
}
|
1589
|
+
|
1590
|
+
async fetchFundingHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
1591
|
+
await this.loadMarkets ();
|
1592
|
+
// let defaultType = 'future';
|
1593
|
+
let market = undefined;
|
1594
|
+
let request = {};
|
1595
|
+
if (symbol !== undefined) {
|
1596
|
+
market = this.market (symbol);
|
1597
|
+
symbol = market['symbol'];
|
1598
|
+
request = this.prepareRequest (market);
|
1599
|
+
}
|
1600
|
+
let type = undefined;
|
1601
|
+
[ type, params ] = this.handleMarketTypeAndParams ('fetchFundingHistory', market, params);
|
1602
|
+
if (market === undefined) {
|
1603
|
+
const defaultSettle = (type === 'swap') ? 'usdt' : 'btc';
|
1604
|
+
const settle = this.safeString (params, 'settle', defaultSettle);
|
1605
|
+
request['settle'] = settle;
|
1606
|
+
params = this.omit (params, 'settle');
|
1607
|
+
}
|
1608
|
+
request['type'] = 'fund'; // 'dnw' 'pnl' 'fee' 'refr' 'fund' 'point_dnw' 'point_fee' 'point_refr'
|
1609
|
+
if (since !== undefined) {
|
1610
|
+
request['from'] = since / 1000;
|
1611
|
+
}
|
1612
|
+
if (limit !== undefined) {
|
1613
|
+
request['limit'] = limit;
|
1614
|
+
}
|
1615
|
+
const method = this.getSupportedMapping (type, {
|
1616
|
+
'swap': 'privateFuturesGetSettleAccountBook',
|
1617
|
+
'future': 'privateDeliveryGetSettleAccountBook',
|
1618
|
+
});
|
1619
|
+
const response = await this[method] (this.extend (request, params));
|
1620
|
+
//
|
1621
|
+
// [
|
1622
|
+
// {
|
1623
|
+
// "time": 1646899200,
|
1624
|
+
// "change": "-0.027722",
|
1625
|
+
// "balance": "11.653120591841",
|
1626
|
+
// "text": "XRP_USDT",
|
1627
|
+
// "type": "fund"
|
1628
|
+
// },
|
1629
|
+
// ...
|
1630
|
+
// ]
|
1631
|
+
//
|
1632
|
+
return this.parseFundingHistories (response, symbol, since, limit);
|
1633
|
+
}
|
1634
|
+
|
1635
|
+
parseFundingHistories (response, symbol, since, limit) {
|
1636
|
+
const result = [];
|
1637
|
+
for (let i = 0; i < response.length; i++) {
|
1638
|
+
const entry = response[i];
|
1639
|
+
const funding = this.parseFundingHistory (entry);
|
1640
|
+
result.push (funding);
|
1641
|
+
}
|
1642
|
+
const sorted = this.sortBy (result, 'timestamp');
|
1643
|
+
return this.filterBySymbolSinceLimit (sorted, symbol, since, limit);
|
1644
|
+
}
|
1645
|
+
|
1646
|
+
parseFundingHistory (info, market = undefined) {
|
1647
|
+
//
|
1648
|
+
// {
|
1649
|
+
// "time": 1646899200,
|
1650
|
+
// "change": "-0.027722",
|
1651
|
+
// "balance": "11.653120591841",
|
1652
|
+
// "text": "XRP_USDT",
|
1653
|
+
// "type": "fund"
|
1654
|
+
// }
|
1655
|
+
//
|
1656
|
+
const timestamp = this.safeTimestamp (info, 'time');
|
1657
|
+
const marketId = this.safeString (info, 'text');
|
1658
|
+
market = this.safeMarket (marketId, market);
|
1659
|
+
return {
|
1660
|
+
'info': info,
|
1661
|
+
'symbol': this.safeString (market, 'symbol'),
|
1662
|
+
'code': this.safeString (market, 'settle'),
|
1663
|
+
'timestamp': timestamp,
|
1664
|
+
'datetime': this.iso8601 (timestamp),
|
1665
|
+
'id': undefined,
|
1666
|
+
'amount': this.safeNumber (info, 'change'),
|
1667
|
+
};
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
1671
|
+
await this.loadMarkets ();
|
1672
|
+
const market = this.market (symbol);
|
1673
|
+
//
|
1674
|
+
// const request = {
|
1675
|
+
// 'currency_pair': market['id'],
|
1676
|
+
// 'interval': '0', // depth, 0 means no aggregation is applied, default to 0
|
1677
|
+
// 'limit': limit, // maximum number of order depth data in asks or bids
|
1678
|
+
// 'with_id': true, // return order book ID
|
1679
|
+
// };
|
1680
|
+
//
|
1681
|
+
const request = this.prepareRequest (market);
|
1682
|
+
const spotOrMargin = market['spot'] || market['margin'];
|
1683
|
+
const method = this.getSupportedMapping (market['type'], {
|
1684
|
+
'spot': 'publicSpotGetOrderBook',
|
1685
|
+
'margin': 'publicSpotGetOrderBook',
|
1686
|
+
'swap': 'publicFuturesGetSettleOrderBook',
|
1687
|
+
'future': 'publicDeliveryGetSettleOrderBook',
|
1688
|
+
});
|
1689
|
+
if (limit !== undefined) {
|
1690
|
+
request['limit'] = limit; // default 10, max 100
|
1691
|
+
}
|
1692
|
+
request['with_id'] = true;
|
1693
|
+
const response = await this[method] (this.extend (request, params));
|
1694
|
+
//
|
1695
|
+
// SPOT
|
1696
|
+
//
|
1697
|
+
// {
|
1698
|
+
// "id": 6358770031
|
1699
|
+
// "current": 1634345973275,
|
1700
|
+
// "update": 1634345973271,
|
1701
|
+
// "asks": [
|
1702
|
+
// ["2.2241","12449.827"],
|
1703
|
+
// ["2.2242","200"],
|
1704
|
+
// ["2.2244","826.931"],
|
1705
|
+
// ["2.2248","3876.107"],
|
1706
|
+
// ["2.225","2377.252"],
|
1707
|
+
// ["2.22509","439.484"],
|
1708
|
+
// ["2.2251","1489.313"],
|
1709
|
+
// ["2.2253","714.582"],
|
1710
|
+
// ["2.2254","1349.784"],
|
1711
|
+
// ["2.2256","234.701"]],
|
1712
|
+
// "bids": [
|
1713
|
+
// ["2.2236","32.465"],
|
1714
|
+
// ["2.2232","243.983"],
|
1715
|
+
// ["2.2231","32.207"],
|
1716
|
+
// ["2.223","449.827"],
|
1717
|
+
// ["2.2228","7.918"],
|
1718
|
+
// ["2.2227","12703.482"],
|
1719
|
+
// ["2.2226","143.033"],
|
1720
|
+
// ["2.2225","143.027"],
|
1721
|
+
// ["2.2224","1369.352"],
|
1722
|
+
// ["2.2223","756.063"]
|
1723
|
+
// ]
|
1724
|
+
// }
|
1725
|
+
//
|
1726
|
+
// Perpetual Swap
|
1727
|
+
//
|
1728
|
+
// {
|
1729
|
+
// "id": 6358770031
|
1730
|
+
// "current": 1634350208.745,
|
1731
|
+
// "asks": [
|
1732
|
+
// {"s": 24909, "p": "61264.8"},
|
1733
|
+
// {"s": 81, "p": "61266.6"},
|
1734
|
+
// {"s": 2000, "p": "61267.6"},
|
1735
|
+
// {"s": 490, "p": "61270.2"},
|
1736
|
+
// {"s": 12, "p": "61270.4"},
|
1737
|
+
// {"s": 11782, "p": "61273.2"},
|
1738
|
+
// {"s": 14666, "p": "61273.3"},
|
1739
|
+
// {"s": 22541, "p": "61273.4"},
|
1740
|
+
// {"s": 33, "p": "61273.6"},
|
1741
|
+
// {"s": 11980, "p": "61274.5"}
|
1742
|
+
// ],
|
1743
|
+
// "bids": [
|
1744
|
+
// {"s": 41844, "p": "61264.7"},
|
1745
|
+
// {"s": 13783, "p": "61263.3"},
|
1746
|
+
// {"s": 1143, "p": "61259.8"},
|
1747
|
+
// {"s": 81, "p": "61258.7"},
|
1748
|
+
// {"s": 2471, "p": "61257.8"},
|
1749
|
+
// {"s": 2471, "p": "61257.7"},
|
1750
|
+
// {"s": 2471, "p": "61256.5"},
|
1751
|
+
// {"s": 3, "p": "61254.2"},
|
1752
|
+
// {"s": 114, "p": "61252.4"},
|
1753
|
+
// {"s": 14372, "p": "61248.6"}
|
1754
|
+
// ],
|
1755
|
+
// "update": 1634350208.724
|
1756
|
+
// }
|
1757
|
+
//
|
1758
|
+
let timestamp = this.safeInteger (response, 'current');
|
1759
|
+
if (!spotOrMargin) {
|
1760
|
+
timestamp = timestamp * 1000;
|
1761
|
+
}
|
1762
|
+
const priceKey = spotOrMargin ? 0 : 'p';
|
1763
|
+
const amountKey = spotOrMargin ? 1 : 's';
|
1764
|
+
const nonce = this.safeInteger (response, 'id');
|
1765
|
+
const result = this.parseOrderBook (response, symbol, timestamp, 'bids', 'asks', priceKey, amountKey);
|
1766
|
+
result['nonce'] = nonce;
|
1767
|
+
return result;
|
1768
|
+
}
|
1769
|
+
|
1770
|
+
async fetchTicker (symbol, params = {}) {
|
1771
|
+
await this.loadMarkets ();
|
1772
|
+
const market = this.market (symbol);
|
1773
|
+
const request = this.prepareRequest (market);
|
1774
|
+
const method = this.getSupportedMapping (market['type'], {
|
1775
|
+
'spot': 'publicSpotGetTickers',
|
1776
|
+
'margin': 'publicSpotGetTickers',
|
1777
|
+
'swap': 'publicFuturesGetSettleTickers',
|
1778
|
+
'future': 'publicDeliveryGetSettleTickers',
|
1779
|
+
});
|
1780
|
+
const response = await this[method] (this.extend (request, params));
|
1781
|
+
const ticker = this.safeValue (response, 0);
|
1782
|
+
return this.parseTicker (ticker, market);
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
parseTicker (ticker, market = undefined) {
|
1786
|
+
//
|
1787
|
+
// SPOT
|
1788
|
+
//
|
1789
|
+
// {
|
1790
|
+
// "currency_pair": "KFC_USDT",
|
1791
|
+
// "last": "7.255",
|
1792
|
+
// "lowest_ask": "7.298",
|
1793
|
+
// "highest_bid": "7.218",
|
1794
|
+
// "change_percentage": "-1.18",
|
1795
|
+
// "base_volume": "1219.053687865",
|
1796
|
+
// "quote_volume": "8807.40299875455",
|
1797
|
+
// "high_24h": "7.262",
|
1798
|
+
// "low_24h": "7.095"
|
1799
|
+
// }
|
1800
|
+
//
|
1801
|
+
// LINEAR/DELIVERY
|
1802
|
+
//
|
1803
|
+
// {
|
1804
|
+
// "contract": "BTC_USDT",
|
1805
|
+
// "last": "6432",
|
1806
|
+
// "low_24h": "6278",
|
1807
|
+
// "high_24h": "6790",
|
1808
|
+
// "change_percentage": "4.43",
|
1809
|
+
// "total_size": "32323904",
|
1810
|
+
// "volume_24h": "184040233284",
|
1811
|
+
// "volume_24h_btc": "28613220",
|
1812
|
+
// "volume_24h_usd": "184040233284",
|
1813
|
+
// "volume_24h_base": "28613220",
|
1814
|
+
// "volume_24h_quote": "184040233284",
|
1815
|
+
// "volume_24h_settle": "28613220",
|
1816
|
+
// "mark_price": "6534",
|
1817
|
+
// "funding_rate": "0.0001",
|
1818
|
+
// "funding_rate_indicative": "0.0001",
|
1819
|
+
// "index_price": "6531"
|
1820
|
+
// }
|
1821
|
+
//
|
1822
|
+
const marketId = this.safeString2 (ticker, 'currency_pair', 'contract');
|
1823
|
+
const symbol = this.safeSymbol (marketId, market);
|
1824
|
+
const last = this.safeString (ticker, 'last');
|
1825
|
+
const ask = this.safeString (ticker, 'lowest_ask');
|
1826
|
+
const bid = this.safeString (ticker, 'highest_bid');
|
1827
|
+
const high = this.safeString (ticker, 'high_24h');
|
1828
|
+
const low = this.safeString (ticker, 'low_24h');
|
1829
|
+
const baseVolume = this.safeString2 (ticker, 'base_volume', 'volume_24h_base');
|
1830
|
+
const quoteVolume = this.safeString2 (ticker, 'quote_volume', 'volume_24h_quote');
|
1831
|
+
const percentage = this.safeString (ticker, 'change_percentage');
|
1832
|
+
return this.safeTicker ({
|
1833
|
+
'symbol': symbol,
|
1834
|
+
'timestamp': undefined,
|
1835
|
+
'datetime': undefined,
|
1836
|
+
'high': high,
|
1837
|
+
'low': low,
|
1838
|
+
'bid': bid,
|
1839
|
+
'bidVolume': undefined,
|
1840
|
+
'ask': ask,
|
1841
|
+
'askVolume': undefined,
|
1842
|
+
'vwap': undefined,
|
1843
|
+
'open': undefined,
|
1844
|
+
'close': last,
|
1845
|
+
'last': last,
|
1846
|
+
'previousClose': undefined,
|
1847
|
+
'change': undefined,
|
1848
|
+
'percentage': percentage,
|
1849
|
+
'average': undefined,
|
1850
|
+
'baseVolume': baseVolume,
|
1851
|
+
'quoteVolume': quoteVolume,
|
1852
|
+
'info': ticker,
|
1853
|
+
}, market, false);
|
1854
|
+
}
|
1855
|
+
|
1856
|
+
async fetchTickers (symbols = undefined, params = {}) {
|
1857
|
+
await this.loadMarkets ();
|
1858
|
+
let type = undefined;
|
1859
|
+
[ type, params ] = this.handleMarketTypeAndParams ('fetchTickers', undefined, params);
|
1860
|
+
const method = this.getSupportedMapping (type, {
|
1861
|
+
'spot': 'publicSpotGetTickers',
|
1862
|
+
'margin': 'publicSpotGetTickers',
|
1863
|
+
'swap': 'publicFuturesGetSettleTickers',
|
1864
|
+
'future': 'publicDeliveryGetSettleTickers',
|
1865
|
+
});
|
1866
|
+
const request = {};
|
1867
|
+
const future = type === 'future';
|
1868
|
+
const swap = type === 'swap';
|
1869
|
+
const defaultSettle = swap ? 'usdt' : 'btc';
|
1870
|
+
const settle = this.safeStringLower (params, 'settle', defaultSettle);
|
1871
|
+
if (swap || future) {
|
1872
|
+
request['settle'] = settle;
|
1873
|
+
}
|
1874
|
+
const response = await this[method] (this.extend (request, params));
|
1875
|
+
return this.parseTickers (response, symbols);
|
1876
|
+
}
|
1877
|
+
|
1878
|
+
fetchBalanceHelper (entry) {
|
1879
|
+
const account = this.account ();
|
1880
|
+
account['used'] = this.safeString2 (entry, 'freeze', 'locked');
|
1881
|
+
account['free'] = this.safeString (entry, 'available');
|
1882
|
+
account['total'] = this.safeString (entry, 'total');
|
1883
|
+
return account;
|
1884
|
+
}
|
1885
|
+
|
1886
|
+
async fetchBalance (params = {}) {
|
1887
|
+
/**
|
1888
|
+
* @param {dict} params exchange specific parameters
|
1889
|
+
* @param {str} params.type spot, margin, swap or future, if not provided this.options['defaultType'] is used
|
1890
|
+
* @param {str} params.settle 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
|
1891
|
+
* @param {str} params.marginType 'cross' or 'isolated' - marginType for margin trading if not provided this.options['defaultMarginType'] is used
|
1892
|
+
* @param {str} params.symbol margin only - unified ccxt symbol
|
1893
|
+
*/
|
1894
|
+
await this.loadMarkets ();
|
1895
|
+
let type = undefined;
|
1896
|
+
let marginType = undefined;
|
1897
|
+
[ type, params ] = this.handleMarketTypeAndParams ('fetchBalance', undefined, params);
|
1898
|
+
const spot = type === 'spot';
|
1899
|
+
const swap = type === 'swap';
|
1900
|
+
const future = type === 'future';
|
1901
|
+
const contract = swap || future;
|
1902
|
+
const request = {};
|
1903
|
+
if (contract) {
|
1904
|
+
const defaultSettle = swap ? 'usdt' : 'btc';
|
1905
|
+
const settle = this.safeStringLower (params, 'settle', defaultSettle);
|
1906
|
+
params = this.omit (params, 'settle');
|
1907
|
+
request['settle'] = settle;
|
1908
|
+
} else {
|
1909
|
+
[ marginType, params ] = this.getMarginType (false, params);
|
1910
|
+
const symbol = this.safeString (params, 'symbol');
|
1911
|
+
if (symbol !== undefined) {
|
1912
|
+
const market = this.market (symbol);
|
1913
|
+
request['currency_pair'] = market['id'];
|
1914
|
+
}
|
1915
|
+
}
|
1916
|
+
const crossMargin = marginType === 'cross_margin';
|
1917
|
+
const margin = marginType === 'margin';
|
1918
|
+
let spotMethod = 'privateSpotGetAccounts';
|
1919
|
+
if (spot) {
|
1920
|
+
spotMethod = this.getSupportedMapping (marginType, {
|
1921
|
+
'spot': 'privateSpotGetAccounts',
|
1922
|
+
'margin': 'privateMarginGetAccounts',
|
1923
|
+
'cross_margin': 'privateMarginGetCrossAccounts',
|
1924
|
+
});
|
1925
|
+
}
|
1926
|
+
const method = this.getSupportedMapping (type, {
|
1927
|
+
'spot': spotMethod,
|
1928
|
+
'funding': 'privateMarginGetFundingAccounts',
|
1929
|
+
'swap': 'privateFuturesGetSettleAccounts',
|
1930
|
+
'future': 'privateDeliveryGetSettleAccounts',
|
1931
|
+
});
|
1932
|
+
let response = await this[method] (this.extend (request, params));
|
1933
|
+
if (contract) {
|
1934
|
+
response = [ response ];
|
1935
|
+
}
|
1936
|
+
//
|
1937
|
+
// Spot / margin funding
|
1938
|
+
//
|
1939
|
+
// [
|
1940
|
+
// {
|
1941
|
+
// "currency": "DBC",
|
1942
|
+
// "available": "0",
|
1943
|
+
// "locked": "0"
|
1944
|
+
// "lent": "0", // margin funding only
|
1945
|
+
// "total_lent": "0" // margin funding only
|
1946
|
+
// },
|
1947
|
+
// ...
|
1948
|
+
// ]
|
1949
|
+
//
|
1950
|
+
// Margin
|
1951
|
+
//
|
1952
|
+
// [
|
1953
|
+
// {
|
1954
|
+
// "currency_pair": "DOGE_USDT",
|
1955
|
+
// "locked": false,
|
1956
|
+
// "risk": "9999.99",
|
1957
|
+
// "base": {
|
1958
|
+
// "currency": "DOGE",
|
1959
|
+
// "available": "0",
|
1960
|
+
// "locked": "0",
|
1961
|
+
// "borrowed": "0",
|
1962
|
+
// "interest": "0"
|
1963
|
+
// },
|
1964
|
+
// "quote": {
|
1965
|
+
// "currency": "USDT",
|
1966
|
+
// "available": "0.73402",
|
1967
|
+
// "locked": "0",
|
1968
|
+
// "borrowed": "0",
|
1969
|
+
// "interest": "0"
|
1970
|
+
// }
|
1971
|
+
// },
|
1972
|
+
// ...
|
1973
|
+
// ]
|
1974
|
+
//
|
1975
|
+
// Cross margin
|
1976
|
+
//
|
1977
|
+
// {
|
1978
|
+
// "user_id": 10406147,
|
1979
|
+
// "locked": false,
|
1980
|
+
// "balances": {
|
1981
|
+
// "USDT": {
|
1982
|
+
// "available": "1",
|
1983
|
+
// "freeze": "0",
|
1984
|
+
// "borrowed": "0",
|
1985
|
+
// "interest": "0"
|
1986
|
+
// }
|
1987
|
+
// },
|
1988
|
+
// "total": "1",
|
1989
|
+
// "borrowed": "0",
|
1990
|
+
// "interest": "0",
|
1991
|
+
// "risk": "9999.99"
|
1992
|
+
// }
|
1993
|
+
//
|
1994
|
+
// Perpetual Swap
|
1995
|
+
//
|
1996
|
+
// {
|
1997
|
+
// order_margin: "0",
|
1998
|
+
// point: "0",
|
1999
|
+
// bonus: "0",
|
2000
|
+
// history: {
|
2001
|
+
// dnw: "2.1321",
|
2002
|
+
// pnl: "11.5351",
|
2003
|
+
// refr: "0",
|
2004
|
+
// point_fee: "0",
|
2005
|
+
// fund: "-0.32340576684",
|
2006
|
+
// bonus_dnw: "0",
|
2007
|
+
// point_refr: "0",
|
2008
|
+
// bonus_offset: "0",
|
2009
|
+
// fee: "-0.20132775",
|
2010
|
+
// point_dnw: "0",
|
2011
|
+
// },
|
2012
|
+
// unrealised_pnl: "13.315100000006",
|
2013
|
+
// total: "12.51345151332",
|
2014
|
+
// available: "0",
|
2015
|
+
// in_dual_mode: false,
|
2016
|
+
// currency: "USDT",
|
2017
|
+
// position_margin: "12.51345151332",
|
2018
|
+
// user: "6333333",
|
2019
|
+
// }
|
2020
|
+
//
|
2021
|
+
// Delivery Future
|
2022
|
+
//
|
2023
|
+
// {
|
2024
|
+
// order_margin: "0",
|
2025
|
+
// point: "0",
|
2026
|
+
// history: {
|
2027
|
+
// dnw: "1",
|
2028
|
+
// pnl: "0",
|
2029
|
+
// refr: "0",
|
2030
|
+
// point_fee: "0",
|
2031
|
+
// point_dnw: "0",
|
2032
|
+
// settle: "0",
|
2033
|
+
// settle_fee: "0",
|
2034
|
+
// point_refr: "0",
|
2035
|
+
// fee: "0",
|
2036
|
+
// },
|
2037
|
+
// unrealised_pnl: "0",
|
2038
|
+
// total: "1",
|
2039
|
+
// available: "1",
|
2040
|
+
// currency: "USDT",
|
2041
|
+
// position_margin: "0",
|
2042
|
+
// user: "6333333",
|
2043
|
+
// }
|
2044
|
+
//
|
2045
|
+
const result = {
|
2046
|
+
'info': response,
|
2047
|
+
};
|
2048
|
+
let data = response;
|
2049
|
+
if ('balances' in data) { // True for cross_margin
|
2050
|
+
const flatBalances = [];
|
2051
|
+
const balances = this.safeValue (data, 'balances', []);
|
2052
|
+
// inject currency and create an artificial balance object
|
2053
|
+
// so it can follow the existent flow
|
2054
|
+
const keys = Object.keys (balances);
|
2055
|
+
for (let i = 0; i < keys.length; i++) {
|
2056
|
+
const currencyId = keys[i];
|
2057
|
+
const content = balances[currencyId];
|
2058
|
+
content['currency'] = currencyId;
|
2059
|
+
flatBalances.push (content);
|
2060
|
+
}
|
2061
|
+
data = flatBalances;
|
2062
|
+
}
|
2063
|
+
for (let i = 0; i < data.length; i++) {
|
2064
|
+
const entry = data[i];
|
2065
|
+
if (margin && !crossMargin) {
|
2066
|
+
const marketId = this.safeString (entry, 'currency_pair');
|
2067
|
+
const symbol = this.safeSymbol (marketId, undefined, '_');
|
2068
|
+
const base = this.safeValue (entry, 'base', {});
|
2069
|
+
const quote = this.safeValue (entry, 'quote', {});
|
2070
|
+
const baseCode = this.safeCurrencyCode (this.safeString (base, 'currency', {}));
|
2071
|
+
const quoteCode = this.safeCurrencyCode (this.safeString (quote, 'currency', {}));
|
2072
|
+
const subResult = {};
|
2073
|
+
subResult[baseCode] = this.fetchBalanceHelper (base);
|
2074
|
+
subResult[quoteCode] = this.fetchBalanceHelper (quote);
|
2075
|
+
result[symbol] = this.safeBalance (subResult);
|
2076
|
+
} else {
|
2077
|
+
const code = this.safeCurrencyCode (this.safeString (entry, 'currency', {}));
|
2078
|
+
result[code] = this.fetchBalanceHelper (entry);
|
2079
|
+
}
|
2080
|
+
}
|
2081
|
+
return (margin && !crossMargin) ? result : this.safeBalance (result);
|
2082
|
+
}
|
2083
|
+
|
2084
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
2085
|
+
await this.loadMarkets ();
|
2086
|
+
const market = this.market (symbol);
|
2087
|
+
const price = this.safeString (params, 'price');
|
2088
|
+
const request = this.prepareRequest (market);
|
2089
|
+
request['interval'] = this.timeframes[timeframe];
|
2090
|
+
let method = 'publicSpotGetCandlesticks';
|
2091
|
+
if (market['contract']) {
|
2092
|
+
const maxLimit = 1999;
|
2093
|
+
limit = (limit === undefined) ? maxLimit : Math.min (limit, maxLimit);
|
2094
|
+
if (market['future']) {
|
2095
|
+
method = 'publicDeliveryGetSettleCandlesticks';
|
2096
|
+
} else if (market['swap']) {
|
2097
|
+
method = 'publicFuturesGetSettleCandlesticks';
|
2098
|
+
}
|
2099
|
+
const isMark = (price === 'mark');
|
2100
|
+
const isIndex = (price === 'index');
|
2101
|
+
if (isMark || isIndex) {
|
2102
|
+
request['contract'] = price + '_' + market['id'];
|
2103
|
+
params = this.omit (params, 'price');
|
2104
|
+
}
|
2105
|
+
} else {
|
2106
|
+
const maxLimit = 1000;
|
2107
|
+
limit = (limit === undefined) ? maxLimit : Math.min (limit, maxLimit);
|
2108
|
+
request['limit'] = limit;
|
2109
|
+
}
|
2110
|
+
if (since !== undefined) {
|
2111
|
+
const duration = this.parseTimeframe (timeframe);
|
2112
|
+
request['from'] = parseInt (since / 1000);
|
2113
|
+
const toTimestamp = this.sum (request['from'], limit * duration - 1);
|
2114
|
+
const currentTimestamp = this.seconds ();
|
2115
|
+
request['to'] = Math.min (toTimestamp, currentTimestamp);
|
2116
|
+
}
|
2117
|
+
const response = await this[method] (this.extend (request, params));
|
2118
|
+
return this.parseOHLCVs (response, market, timeframe, since, limit);
|
2119
|
+
}
|
2120
|
+
|
2121
|
+
async fetchMarkOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
2122
|
+
const request = {
|
2123
|
+
'price': 'mark',
|
2124
|
+
};
|
2125
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
2126
|
+
}
|
2127
|
+
|
2128
|
+
async fetchFundingRateHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2129
|
+
if (symbol === undefined) {
|
2130
|
+
throw new ArgumentsRequired (this.id + ' fetchFundingRateHistory() requires a symbol argument');
|
2131
|
+
}
|
2132
|
+
await this.loadMarkets ();
|
2133
|
+
const market = this.market (symbol);
|
2134
|
+
if (!market['swap']) {
|
2135
|
+
throw new BadRequest ('Funding rates only exist for swap contracts');
|
2136
|
+
}
|
2137
|
+
const request = {
|
2138
|
+
'contract': market['id'],
|
2139
|
+
'settle': market['settleId'],
|
2140
|
+
};
|
2141
|
+
if (limit !== undefined) {
|
2142
|
+
request['limit'] = limit;
|
2143
|
+
}
|
2144
|
+
const method = 'publicFuturesGetSettleFundingRate';
|
2145
|
+
const response = await this[method] (this.extend (request, params));
|
2146
|
+
//
|
2147
|
+
// {
|
2148
|
+
// "r": "0.00063521",
|
2149
|
+
// "t": "1621267200000",
|
2150
|
+
// }
|
2151
|
+
//
|
2152
|
+
const rates = [];
|
2153
|
+
for (let i = 0; i < response.length; i++) {
|
2154
|
+
const entry = response[i];
|
2155
|
+
const timestamp = this.safeTimestamp (entry, 't');
|
2156
|
+
rates.push ({
|
2157
|
+
'info': entry,
|
2158
|
+
'symbol': symbol,
|
2159
|
+
'fundingRate': this.safeNumber (entry, 'r'),
|
2160
|
+
'timestamp': timestamp,
|
2161
|
+
'datetime': this.iso8601 (timestamp),
|
2162
|
+
});
|
2163
|
+
}
|
2164
|
+
const sorted = this.sortBy (rates, 'timestamp');
|
2165
|
+
return this.filterBySymbolSinceLimit (sorted, market['symbol'], since, limit);
|
2166
|
+
}
|
2167
|
+
|
2168
|
+
async fetchIndexOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
2169
|
+
const request = {
|
2170
|
+
'price': 'index',
|
2171
|
+
};
|
2172
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
2173
|
+
}
|
2174
|
+
|
2175
|
+
parseOHLCV (ohlcv, market = undefined) {
|
2176
|
+
//
|
2177
|
+
// Spot market candles
|
2178
|
+
//
|
2179
|
+
// [
|
2180
|
+
// "1626163200", // Unix timestamp in seconds
|
2181
|
+
// "346711.933138181617", // Trading volume
|
2182
|
+
// "33165.23", // Close price
|
2183
|
+
// "33260", // Highest price
|
2184
|
+
// "33117.6", // Lowest price
|
2185
|
+
// "33184.47" // Open price
|
2186
|
+
// ]
|
2187
|
+
//
|
2188
|
+
// Mark and Index price candles
|
2189
|
+
//
|
2190
|
+
// {
|
2191
|
+
// "t":1632873600, // Unix timestamp in seconds
|
2192
|
+
// "o": "41025", // Open price
|
2193
|
+
// "h": "41882.17", // Highest price
|
2194
|
+
// "c": "41776.92", // Close price
|
2195
|
+
// "l": "40783.94" // Lowest price
|
2196
|
+
// }
|
2197
|
+
//
|
2198
|
+
if (Array.isArray (ohlcv)) {
|
2199
|
+
return [
|
2200
|
+
this.safeTimestamp (ohlcv, 0), // unix timestamp in seconds
|
2201
|
+
this.safeNumber (ohlcv, 5), // open price
|
2202
|
+
this.safeNumber (ohlcv, 3), // highest price
|
2203
|
+
this.safeNumber (ohlcv, 4), // lowest price
|
2204
|
+
this.safeNumber (ohlcv, 2), // close price
|
2205
|
+
this.safeNumber (ohlcv, 1), // trading volume
|
2206
|
+
];
|
2207
|
+
} else {
|
2208
|
+
// Mark and Index price candles
|
2209
|
+
return [
|
2210
|
+
this.safeTimestamp (ohlcv, 't'), // unix timestamp in seconds
|
2211
|
+
this.safeNumber (ohlcv, 'o'), // open price
|
2212
|
+
this.safeNumber (ohlcv, 'h'), // highest price
|
2213
|
+
this.safeNumber (ohlcv, 'l'), // lowest price
|
2214
|
+
this.safeNumber (ohlcv, 'c'), // close price
|
2215
|
+
this.safeNumber (ohlcv, 'v'), // trading volume, undefined for mark or index price
|
2216
|
+
];
|
2217
|
+
}
|
2218
|
+
}
|
2219
|
+
|
2220
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
2221
|
+
await this.loadMarkets ();
|
2222
|
+
const market = this.market (symbol);
|
2223
|
+
//
|
2224
|
+
// spot
|
2225
|
+
//
|
2226
|
+
// const request = {
|
2227
|
+
// 'currency_pair': market['id'],
|
2228
|
+
// 'limit': limit, // maximum number of records to be returned in a single list
|
2229
|
+
// 'last_id': 'id', // specify list staring point using the id of last record in previous list-query results
|
2230
|
+
// 'reverse': false, // true to retrieve records where id is smaller than the specified last_id, false to retrieve records where id is larger than the specified last_id
|
2231
|
+
// };
|
2232
|
+
//
|
2233
|
+
// swap, future
|
2234
|
+
//
|
2235
|
+
// const request = {
|
2236
|
+
// 'settle': market['settleId'],
|
2237
|
+
// 'contract': market['id'],
|
2238
|
+
// 'limit': limit, // maximum number of records to be returned in a single list
|
2239
|
+
// 'last_id': 'id', // specify list staring point using the id of last record in previous list-query results
|
2240
|
+
// 'from': since / 1000), // starting time in seconds, if not specified, to and limit will be used to limit response items
|
2241
|
+
// 'to': this.seconds (), // end time in seconds, default to current time
|
2242
|
+
// };
|
2243
|
+
//
|
2244
|
+
const request = this.prepareRequest (market);
|
2245
|
+
const method = this.getSupportedMapping (market['type'], {
|
2246
|
+
'spot': 'publicSpotGetTrades',
|
2247
|
+
'margin': 'publicSpotGetTrades',
|
2248
|
+
'swap': 'publicFuturesGetSettleTrades',
|
2249
|
+
'future': 'publicDeliveryGetSettleTrades',
|
2250
|
+
});
|
2251
|
+
if (limit !== undefined) {
|
2252
|
+
request['limit'] = limit; // default 100, max 1000
|
2253
|
+
}
|
2254
|
+
if (since !== undefined && (market['contract'])) {
|
2255
|
+
request['from'] = parseInt (since / 1000);
|
2256
|
+
}
|
2257
|
+
const response = await this[method] (this.extend (request, params));
|
2258
|
+
//
|
2259
|
+
// spot
|
2260
|
+
//
|
2261
|
+
// [
|
2262
|
+
// {
|
2263
|
+
// id: "1852958144",
|
2264
|
+
// create_time: "1634673259",
|
2265
|
+
// create_time_ms: "1634673259378.105000",
|
2266
|
+
// currency_pair: "ADA_USDT",
|
2267
|
+
// side: "sell",
|
2268
|
+
// amount: "307.078",
|
2269
|
+
// price: "2.104",
|
2270
|
+
// }
|
2271
|
+
// ]
|
2272
|
+
//
|
2273
|
+
// perpetual swap
|
2274
|
+
//
|
2275
|
+
// [
|
2276
|
+
// {
|
2277
|
+
// size: "2",
|
2278
|
+
// id: "2522911",
|
2279
|
+
// create_time_ms: "1634673380.182",
|
2280
|
+
// create_time: "1634673380.182",
|
2281
|
+
// contract: "ADA_USDT",
|
2282
|
+
// price: "2.10486",
|
2283
|
+
// }
|
2284
|
+
// ]
|
2285
|
+
//
|
2286
|
+
return this.parseTrades (response, market, since, limit);
|
2287
|
+
}
|
2288
|
+
|
2289
|
+
async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2290
|
+
await this.loadMarkets ();
|
2291
|
+
let market = undefined;
|
2292
|
+
let request = {};
|
2293
|
+
let type = undefined;
|
2294
|
+
[ type, params ] = this.handleMarketTypeAndParams ('fetchMyTrades', undefined, params);
|
2295
|
+
if (symbol) {
|
2296
|
+
market = this.market (symbol);
|
2297
|
+
request = this.prepareRequest (market);
|
2298
|
+
type = market['type'];
|
2299
|
+
} else {
|
2300
|
+
if (type === 'swap' || type === 'future') {
|
2301
|
+
const settle = this.safeStringLower (params, 'settle');
|
2302
|
+
if (!settle) {
|
2303
|
+
throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a symbol argument or a settle parameter for ' + type + ' markets');
|
2304
|
+
}
|
2305
|
+
request['settle'] = settle;
|
2306
|
+
}
|
2307
|
+
}
|
2308
|
+
//
|
2309
|
+
// const request = {
|
2310
|
+
// 'currency_pair': market['id'],
|
2311
|
+
// // 'limit': limit,
|
2312
|
+
// // 'page': 0,
|
2313
|
+
// // 'order_id': 'Order ID',
|
2314
|
+
// // 'account': 'spot', // default to spot and margin account if not specified, set to cross_margin to operate against margin account
|
2315
|
+
// // 'from': since, // default to 7 days before current time
|
2316
|
+
// // 'to': this.milliseconds (), // default to current time
|
2317
|
+
// };
|
2318
|
+
//
|
2319
|
+
if (limit !== undefined) {
|
2320
|
+
request['limit'] = limit; // default 100, max 1000
|
2321
|
+
}
|
2322
|
+
if (since !== undefined) {
|
2323
|
+
request['from'] = parseInt (since / 1000);
|
2324
|
+
// request['to'] = since + 7 * 24 * 60 * 60;
|
2325
|
+
}
|
2326
|
+
const method = this.getSupportedMapping (type, {
|
2327
|
+
'spot': 'privateSpotGetMyTrades',
|
2328
|
+
'margin': 'privateSpotGetMyTrades',
|
2329
|
+
'swap': 'privateFuturesGetSettleMyTrades',
|
2330
|
+
'future': 'privateDeliveryGetSettleMyTrades',
|
2331
|
+
});
|
2332
|
+
const response = await this[method] (this.extend (request, params));
|
2333
|
+
//
|
2334
|
+
// spot
|
2335
|
+
//
|
2336
|
+
// [
|
2337
|
+
// {
|
2338
|
+
// "id": "2876130500",
|
2339
|
+
// "create_time": "1645464610",
|
2340
|
+
// "create_time_ms": "1645464610777.399200",
|
2341
|
+
// "currency_pair": "DOGE_USDT",
|
2342
|
+
// "side": "sell",
|
2343
|
+
// "role": "taker",
|
2344
|
+
// "amount": "10.97",
|
2345
|
+
// "price": "0.137384",
|
2346
|
+
// "order_id": "125924049993",
|
2347
|
+
// "fee": "0.00301420496",
|
2348
|
+
// "fee_currency": "USDT",
|
2349
|
+
// "point_fee": "0",
|
2350
|
+
// "gt_fee": "0"
|
2351
|
+
// }
|
2352
|
+
// ]
|
2353
|
+
//
|
2354
|
+
// perpetual swap
|
2355
|
+
//
|
2356
|
+
// [
|
2357
|
+
// {
|
2358
|
+
// "size": -5,
|
2359
|
+
// "order_id": "130264979823",
|
2360
|
+
// "id": 26884791,
|
2361
|
+
// "role": "taker",
|
2362
|
+
// "create_time": 1645465199.5472,
|
2363
|
+
// "contract": "DOGE_USDT",
|
2364
|
+
// "price": "0.136888"
|
2365
|
+
// }
|
2366
|
+
// ]
|
2367
|
+
//
|
2368
|
+
// future
|
2369
|
+
//
|
2370
|
+
// [
|
2371
|
+
// {
|
2372
|
+
// "id": 121234231,
|
2373
|
+
// "create_time": 1514764800.123,
|
2374
|
+
// "contract": "BTC_USDT",
|
2375
|
+
// "order_id": "21893289839",
|
2376
|
+
// "size": 100,
|
2377
|
+
// "price": "100.123",
|
2378
|
+
// "role": "taker"
|
2379
|
+
// }
|
2380
|
+
// ]
|
2381
|
+
//
|
2382
|
+
return this.parseTrades (response, market, since, limit);
|
2383
|
+
}
|
2384
|
+
|
2385
|
+
parseTrade (trade, market = undefined) {
|
2386
|
+
//
|
2387
|
+
// public
|
2388
|
+
//
|
2389
|
+
// {
|
2390
|
+
// "id": "1334253759",
|
2391
|
+
// "create_time": "1626342738",
|
2392
|
+
// "create_time_ms": "1626342738331.497000",
|
2393
|
+
// "currency_pair": "BTC_USDT",
|
2394
|
+
// "side": "sell",
|
2395
|
+
// "amount": "0.0022",
|
2396
|
+
// "price": "32452.16"
|
2397
|
+
// }
|
2398
|
+
//
|
2399
|
+
// public ws
|
2400
|
+
//
|
2401
|
+
// {
|
2402
|
+
// id: 221994511,
|
2403
|
+
// time: 1580311438.618647,
|
2404
|
+
// price: '9309',
|
2405
|
+
// amount: '0.0019',
|
2406
|
+
// type: 'sell'
|
2407
|
+
// }
|
2408
|
+
//
|
2409
|
+
// spot rest
|
2410
|
+
//
|
2411
|
+
// {
|
2412
|
+
// "id": "2876130500",
|
2413
|
+
// "create_time": "1645464610",
|
2414
|
+
// "create_time_ms": "1645464610777.399200",
|
2415
|
+
// "currency_pair": "DOGE_USDT",
|
2416
|
+
// "side": "sell",
|
2417
|
+
// "role": "taker",
|
2418
|
+
// "amount": "10.97",
|
2419
|
+
// "price": "0.137384",
|
2420
|
+
// "order_id": "125924049993",
|
2421
|
+
// "fee": "0.00301420496",
|
2422
|
+
// "fee_currency": "USDT",
|
2423
|
+
// "point_fee": "0","gt_fee":"0"
|
2424
|
+
// }
|
2425
|
+
//
|
2426
|
+
// perpetual swap rest
|
2427
|
+
//
|
2428
|
+
// {
|
2429
|
+
// "size": -5,
|
2430
|
+
// "order_id": "130264979823",
|
2431
|
+
// "id": 26884791,
|
2432
|
+
// "role": "taker",
|
2433
|
+
// "create_time": 1645465199.5472,
|
2434
|
+
// "contract": "DOGE_USDT",
|
2435
|
+
// "price": "0.136888"
|
2436
|
+
// }
|
2437
|
+
//
|
2438
|
+
// future rest
|
2439
|
+
//
|
2440
|
+
// {
|
2441
|
+
// "id": 121234231,
|
2442
|
+
// "create_time": 1514764800.123,
|
2443
|
+
// "contract": "BTC_USDT",
|
2444
|
+
// "order_id": "21893289839",
|
2445
|
+
// "size": 100,
|
2446
|
+
// "price": "100.123",
|
2447
|
+
// "role": "taker"
|
2448
|
+
// }
|
2449
|
+
//
|
2450
|
+
const id = this.safeString (trade, 'id');
|
2451
|
+
let timestamp = this.safeTimestamp2 (trade, 'time', 'create_time');
|
2452
|
+
timestamp = this.safeInteger (trade, 'create_time_ms', timestamp);
|
2453
|
+
const marketId = this.safeString2 (trade, 'currency_pair', 'contract');
|
2454
|
+
const symbol = this.safeSymbol (marketId, market);
|
2455
|
+
let amountString = this.safeString2 (trade, 'amount', 'size');
|
2456
|
+
const priceString = this.safeString (trade, 'price');
|
2457
|
+
const contractSide = Precise.stringLt (amountString, '0') ? 'sell' : 'buy';
|
2458
|
+
amountString = Precise.stringAbs (amountString);
|
2459
|
+
const side = this.safeString2 (trade, 'side', 'type', contractSide);
|
2460
|
+
const orderId = this.safeString (trade, 'order_id');
|
2461
|
+
const gtFee = this.safeString (trade, 'gt_fee');
|
2462
|
+
let feeCurrency = undefined;
|
2463
|
+
let feeCostString = undefined;
|
2464
|
+
if (gtFee === '0') {
|
2465
|
+
feeCurrency = this.safeString (trade, 'fee_currency');
|
2466
|
+
feeCostString = this.safeString (trade, 'fee');
|
2467
|
+
} else {
|
2468
|
+
feeCurrency = 'GT';
|
2469
|
+
feeCostString = gtFee;
|
2470
|
+
}
|
2471
|
+
const fee = {
|
2472
|
+
'cost': feeCostString,
|
2473
|
+
'currency': feeCurrency,
|
2474
|
+
};
|
2475
|
+
const takerOrMaker = this.safeString (trade, 'role');
|
2476
|
+
return this.safeTrade ({
|
2477
|
+
'info': trade,
|
2478
|
+
'id': id,
|
2479
|
+
'timestamp': timestamp,
|
2480
|
+
'datetime': this.iso8601 (timestamp),
|
2481
|
+
'symbol': symbol,
|
2482
|
+
'order': orderId,
|
2483
|
+
'type': undefined,
|
2484
|
+
'side': side,
|
2485
|
+
'takerOrMaker': takerOrMaker,
|
2486
|
+
'price': priceString,
|
2487
|
+
'amount': amountString,
|
2488
|
+
'cost': undefined,
|
2489
|
+
'fee': fee,
|
2490
|
+
}, market);
|
2491
|
+
}
|
2492
|
+
|
2493
|
+
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2494
|
+
await this.loadMarkets ();
|
2495
|
+
const request = {};
|
2496
|
+
let currency = undefined;
|
2497
|
+
if (code !== undefined) {
|
2498
|
+
currency = this.currency (code);
|
2499
|
+
request['currency'] = currency['id'];
|
2500
|
+
}
|
2501
|
+
if (limit !== undefined) {
|
2502
|
+
request['limit'] = limit;
|
2503
|
+
}
|
2504
|
+
if (since !== undefined) {
|
2505
|
+
const start = parseInt (since / 1000);
|
2506
|
+
request['from'] = start;
|
2507
|
+
request['to'] = this.sum (start, 30 * 24 * 60 * 60);
|
2508
|
+
}
|
2509
|
+
const response = await this.privateWalletGetDeposits (this.extend (request, params));
|
2510
|
+
return this.parseTransactions (response, currency);
|
2511
|
+
}
|
2512
|
+
|
2513
|
+
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2514
|
+
await this.loadMarkets ();
|
2515
|
+
const request = {};
|
2516
|
+
let currency = undefined;
|
2517
|
+
if (code !== undefined) {
|
2518
|
+
currency = this.currency (code);
|
2519
|
+
request['currency'] = currency['id'];
|
2520
|
+
}
|
2521
|
+
if (limit !== undefined) {
|
2522
|
+
request['limit'] = limit;
|
2523
|
+
}
|
2524
|
+
if (since !== undefined) {
|
2525
|
+
const start = parseInt (since / 1000);
|
2526
|
+
request['from'] = start;
|
2527
|
+
request['to'] = this.sum (start, 30 * 24 * 60 * 60);
|
2528
|
+
}
|
2529
|
+
const response = await this.privateWalletGetWithdrawals (this.extend (request, params));
|
2530
|
+
return this.parseTransactions (response, currency);
|
2531
|
+
}
|
2532
|
+
|
2533
|
+
async withdraw (code, amount, address, tag = undefined, params = {}) {
|
2534
|
+
[ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
|
2535
|
+
this.checkAddress (address);
|
2536
|
+
await this.loadMarkets ();
|
2537
|
+
const currency = this.currency (code);
|
2538
|
+
const request = {
|
2539
|
+
'currency': currency['id'],
|
2540
|
+
'address': address,
|
2541
|
+
'amount': this.currencyToPrecision (code, amount),
|
2542
|
+
};
|
2543
|
+
if (tag !== undefined) {
|
2544
|
+
request['memo'] = tag;
|
2545
|
+
}
|
2546
|
+
const networks = this.safeValue (this.options, 'networks', {});
|
2547
|
+
let network = this.safeStringUpper (params, 'network'); // this line allows the user to specify either ERC20 or ETH
|
2548
|
+
network = this.safeStringLower (networks, network, network); // handle ETH>ERC20 alias
|
2549
|
+
if (network !== undefined) {
|
2550
|
+
request['chain'] = network;
|
2551
|
+
params = this.omit (params, 'network');
|
2552
|
+
}
|
2553
|
+
const response = await this.privateWithdrawalsPost (this.extend (request, params));
|
2554
|
+
//
|
2555
|
+
// {
|
2556
|
+
// "id": "w13389675",
|
2557
|
+
// "currency": "USDT",
|
2558
|
+
// "amount": "50",
|
2559
|
+
// "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
|
2560
|
+
// "memo": null
|
2561
|
+
// }
|
2562
|
+
//
|
2563
|
+
return this.parseTransaction (response, currency);
|
2564
|
+
}
|
2565
|
+
|
2566
|
+
parseTransactionStatus (status) {
|
2567
|
+
const statuses = {
|
2568
|
+
'PEND': 'pending',
|
2569
|
+
'REQUEST': 'pending',
|
2570
|
+
'DMOVE': 'pending',
|
2571
|
+
'CANCEL': 'failed',
|
2572
|
+
'DONE': 'ok',
|
2573
|
+
'BCODE': 'ok', // GateCode withdrawal
|
2574
|
+
};
|
2575
|
+
return this.safeString (statuses, status, status);
|
2576
|
+
}
|
2577
|
+
|
2578
|
+
parseTransactionType (type) {
|
2579
|
+
const types = {
|
2580
|
+
'd': 'deposit',
|
2581
|
+
'w': 'withdrawal',
|
2582
|
+
};
|
2583
|
+
return this.safeString (types, type, type);
|
2584
|
+
}
|
2585
|
+
|
2586
|
+
parseTransaction (transaction, currency = undefined) {
|
2587
|
+
//
|
2588
|
+
// deposits
|
2589
|
+
//
|
2590
|
+
// {
|
2591
|
+
// "id": "d33361395",
|
2592
|
+
// "currency": "USDT_TRX",
|
2593
|
+
// "address": "TErdnxenuLtXfnMafLbfappYdHtnXQ5U4z",
|
2594
|
+
// "amount": "100",
|
2595
|
+
// "txid": "ae9374de34e558562fe18cbb1bf9ab4d9eb8aa7669d65541c9fa2a532c1474a0",
|
2596
|
+
// "timestamp": "1626345819",
|
2597
|
+
// "status": "DONE",
|
2598
|
+
// "memo": ""
|
2599
|
+
// }
|
2600
|
+
//
|
2601
|
+
// withdraw
|
2602
|
+
//
|
2603
|
+
// {
|
2604
|
+
// "id": "w13389675",
|
2605
|
+
// "currency": "USDT",
|
2606
|
+
// "amount": "50",
|
2607
|
+
// "address": "TUu2rLFrmzUodiWfYki7QCNtv1akL682p1",
|
2608
|
+
// "memo": null
|
2609
|
+
// }
|
2610
|
+
//
|
2611
|
+
const id = this.safeString (transaction, 'id');
|
2612
|
+
let type = undefined;
|
2613
|
+
let amount = this.safeString (transaction, 'amount');
|
2614
|
+
if (id[0] === 'b') {
|
2615
|
+
// GateCode handling
|
2616
|
+
type = Precise.stringGt (amount, '0') ? 'deposit' : 'withdrawal';
|
2617
|
+
amount = Precise.stringAbs (amount);
|
2618
|
+
} else if (id !== undefined) {
|
2619
|
+
type = this.parseTransactionType (id[0]);
|
2620
|
+
}
|
2621
|
+
const currencyId = this.safeString (transaction, 'currency');
|
2622
|
+
const code = this.safeCurrencyCode (currencyId);
|
2623
|
+
const txid = this.safeString (transaction, 'txid');
|
2624
|
+
const rawStatus = this.safeString (transaction, 'status');
|
2625
|
+
const status = this.parseTransactionStatus (rawStatus);
|
2626
|
+
const address = this.safeString (transaction, 'address');
|
2627
|
+
const fee = this.safeNumber (transaction, 'fee');
|
2628
|
+
let tag = this.safeString (transaction, 'memo');
|
2629
|
+
if (tag === '') {
|
2630
|
+
tag = undefined;
|
2631
|
+
}
|
2632
|
+
const timestamp = this.safeTimestamp (transaction, 'timestamp');
|
2633
|
+
return {
|
2634
|
+
'info': transaction,
|
2635
|
+
'id': id,
|
2636
|
+
'txid': txid,
|
2637
|
+
'currency': code,
|
2638
|
+
'amount': this.parseNumber (amount),
|
2639
|
+
'network': undefined,
|
2640
|
+
'address': address,
|
2641
|
+
'addressTo': undefined,
|
2642
|
+
'addressFrom': undefined,
|
2643
|
+
'tag': tag,
|
2644
|
+
'tagTo': undefined,
|
2645
|
+
'tagFrom': undefined,
|
2646
|
+
'status': status,
|
2647
|
+
'type': type,
|
2648
|
+
'timestamp': timestamp,
|
2649
|
+
'datetime': this.iso8601 (timestamp),
|
2650
|
+
'updated': undefined,
|
2651
|
+
'fee': fee,
|
2652
|
+
};
|
2653
|
+
}
|
2654
|
+
|
2655
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
2656
|
+
/**
|
2657
|
+
* @method
|
2658
|
+
* @name gateio#createOrder
|
2659
|
+
* @description Create an order on the exchange
|
2660
|
+
* @param {str} symbol Unified CCXT market symbol
|
2661
|
+
* @param {str} type "limit" or "market" *"market" is contract only*
|
2662
|
+
* @param {str} side "buy" or "sell"
|
2663
|
+
* @param {float} amount the amount of currency to trade
|
2664
|
+
* @param {float} price *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
|
2665
|
+
* @param {dict} params Extra parameters specific to the exchange API endpoint
|
2666
|
+
* @param {float} params.stopPrice The price at which a trigger order is triggered at
|
2667
|
+
* @param {str} params.timeInForce "GTC", "IOC", or "PO"
|
2668
|
+
* @param {str} params.marginType 'cross' or 'isolated' - marginType for margin trading if not provided this.options['defaultMarginType'] is used
|
2669
|
+
* @param {int} params.iceberg Amount to display for the iceberg order, Null or 0 for normal orders, Set to -1 to hide the order completely
|
2670
|
+
* @param {str} params.text User defined information
|
2671
|
+
* @param {str} params.account *spot and margin only* "spot", "margin" or "cross_margin"
|
2672
|
+
* @param {bool} params.auto_borrow *margin only* Used in margin or cross margin trading to allow automatic loan of insufficient amount if balance is not enough
|
2673
|
+
* @param {str} params.settle *contract only* Unified Currency Code for settle currency
|
2674
|
+
* @param {bool} params.reduceOnly *contract only* Indicates if this order is to reduce the size of a position
|
2675
|
+
* @param {bool} params.close *contract only* Set as true to close the position, with size set to 0
|
2676
|
+
* @param {bool} params.auto_size *contract only* Set side to close dual-mode position, close_long closes the long side, while close_short the short one, size also needs to be set to 0
|
2677
|
+
* @returns [An order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure}
|
2678
|
+
*/
|
2679
|
+
await this.loadMarkets ();
|
2680
|
+
const market = this.market (symbol);
|
2681
|
+
const contract = market['contract'];
|
2682
|
+
const stopPrice = this.safeNumber (params, 'stopPrice');
|
2683
|
+
let methodTail = 'Orders';
|
2684
|
+
const reduceOnly = this.safeValue2 (params, 'reduce_only', 'reduceOnly');
|
2685
|
+
const defaultTimeInForce = this.safeValue2 (params, 'tif', 'time_in_force', 'gtc');
|
2686
|
+
let timeInForce = this.safeValue (params, 'timeInForce', defaultTimeInForce);
|
2687
|
+
let postOnly = false;
|
2688
|
+
[ type, postOnly, timeInForce, params ] = this.isPostOnly (type, timeInForce, undefined, params);
|
2689
|
+
params = this.omit (params, [ 'stopPrice', 'reduce_only', 'reduceOnly', 'tif', 'time_in_force', 'timeInForce' ]);
|
2690
|
+
if (postOnly) {
|
2691
|
+
timeInForce = 'poc';
|
2692
|
+
}
|
2693
|
+
const isLimitOrder = (type === 'limit');
|
2694
|
+
const isMarketOrder = (type === 'market');
|
2695
|
+
if (isLimitOrder && price === undefined) {
|
2696
|
+
throw new ArgumentsRequired (this.id + ' createOrder() requires a price argument for ' + type + ' orders');
|
2697
|
+
}
|
2698
|
+
if (contract) {
|
2699
|
+
const amountToPrecision = this.amountToPrecision (symbol, amount);
|
2700
|
+
const signedAmount = (side === 'sell') ? Precise.stringNeg (amountToPrecision) : amountToPrecision;
|
2701
|
+
amount = parseInt (signedAmount);
|
2702
|
+
if (isMarketOrder) {
|
2703
|
+
timeInForce = 'ioc';
|
2704
|
+
price = 0;
|
2705
|
+
}
|
2706
|
+
} else if (!isLimitOrder) {
|
2707
|
+
// Gateio doesn't have market orders for spot
|
2708
|
+
throw new InvalidOrder (this.id + ' createOrder() does not support ' + type + ' orders for ' + market['type'] + ' markets');
|
2709
|
+
}
|
2710
|
+
let request = undefined;
|
2711
|
+
const trigger = this.safeValue (params, 'trigger');
|
2712
|
+
if (stopPrice === undefined && trigger === undefined) {
|
2713
|
+
if (contract) {
|
2714
|
+
// contract order
|
2715
|
+
request = {
|
2716
|
+
'contract': market['id'], // filled in prepareRequest above
|
2717
|
+
'size': amount, // int64, positive = bid, negative = ask
|
2718
|
+
// 'iceberg': 0, // int64, display size for iceberg order, 0 for non-iceberg, note that you will have to pay the taker fee for the hidden size
|
2719
|
+
'price': this.priceToPrecision (symbol, price), // 0 for market order with tif set as ioc
|
2720
|
+
// 'close': false, // true to close the position, with size set to 0
|
2721
|
+
// 'reduce_only': false, // St as true to be reduce-only order
|
2722
|
+
// 'tif': 'gtc', // gtc, ioc, poc PendingOrCancelled == postOnly order
|
2723
|
+
// 'text': clientOrderId, // 't-abcdef1234567890',
|
2724
|
+
// 'auto_size': '', // close_long, close_short, note size also needs to be set to 0
|
2725
|
+
'settle': market['settleId'], // filled in prepareRequest above
|
2726
|
+
};
|
2727
|
+
if (reduceOnly !== undefined) {
|
2728
|
+
request['reduce_only'] = reduceOnly;
|
2729
|
+
}
|
2730
|
+
if (timeInForce !== undefined) {
|
2731
|
+
request['tif'] = timeInForce;
|
2732
|
+
}
|
2733
|
+
} else {
|
2734
|
+
let marginType = undefined;
|
2735
|
+
[ marginType, params ] = this.getMarginType (false, params);
|
2736
|
+
params = this.omit (params, 'account');
|
2737
|
+
// spot order
|
2738
|
+
request = {
|
2739
|
+
// 'text': clientOrderId, // 't-abcdef1234567890',
|
2740
|
+
'currency_pair': market['id'], // filled in prepareRequest above
|
2741
|
+
'type': type,
|
2742
|
+
'account': marginType, // 'spot', 'margin', 'cross_margin'
|
2743
|
+
'side': side,
|
2744
|
+
'amount': this.amountToPrecision (symbol, amount),
|
2745
|
+
'price': this.priceToPrecision (symbol, price),
|
2746
|
+
// 'time_in_force': 'gtc', // gtc, ioc, poc PendingOrCancelled == postOnly order
|
2747
|
+
// 'iceberg': 0, // amount to display for the iceberg order, null or 0 for normal orders, set to -1 to hide the order completely
|
2748
|
+
// 'auto_borrow': false, // used in margin or cross margin trading to allow automatic loan of insufficient amount if balance is not enough
|
2749
|
+
// 'auto_repay': false, // automatic repayment for automatic borrow loan generated by cross margin order, diabled by default
|
2750
|
+
};
|
2751
|
+
if (timeInForce !== undefined) {
|
2752
|
+
request['time_in_force'] = timeInForce;
|
2753
|
+
}
|
2754
|
+
}
|
2755
|
+
let clientOrderId = this.safeString2 (params, 'text', 'clientOrderId');
|
2756
|
+
if (clientOrderId !== undefined) {
|
2757
|
+
// user-defined, must follow the rules if not empty
|
2758
|
+
// prefixed with t-
|
2759
|
+
// no longer than 28 bytes without t- prefix
|
2760
|
+
// can only include 0-9, A-Z, a-z, underscores (_), hyphens (-) or dots (.)
|
2761
|
+
if (clientOrderId.length > 28) {
|
2762
|
+
throw new BadRequest (this.id + ' createOrder() clientOrderId or text param must be up to 28 characters');
|
2763
|
+
}
|
2764
|
+
params = this.omit (params, [ 'text', 'clientOrderId' ]);
|
2765
|
+
if (clientOrderId[0] !== 't') {
|
2766
|
+
clientOrderId = 't-' + clientOrderId;
|
2767
|
+
}
|
2768
|
+
request['text'] = clientOrderId;
|
2769
|
+
}
|
2770
|
+
} else {
|
2771
|
+
if (contract) {
|
2772
|
+
// contract conditional order
|
2773
|
+
const rule = (side === 'buy') ? 1 : 2;
|
2774
|
+
request = {
|
2775
|
+
'initial': {
|
2776
|
+
'contract': market['id'],
|
2777
|
+
'size': amount, // positive = buy, negative = sell, set to 0 to close the position
|
2778
|
+
'price': this.priceToPrecision (symbol, price), // set to 0 to use market price
|
2779
|
+
// 'close': false, // set to true if trying to close the position
|
2780
|
+
// 'tif': 'gtc', // gtc, ioc, if using market price, only ioc is supported
|
2781
|
+
// 'text': clientOrderId, // web, api, app
|
2782
|
+
// 'reduce_only': false,
|
2783
|
+
},
|
2784
|
+
'trigger': {
|
2785
|
+
// 'strategy_type': 0, // 0 = by price, 1 = by price gap, only 0 is supported currently
|
2786
|
+
// 'price_type': 0, // 0 latest deal price, 1 mark price, 2 index price
|
2787
|
+
'price': this.priceToPrecision (symbol, stopPrice), // price or gap
|
2788
|
+
'rule': rule, // 1 means price_type >= price, 2 means price_type <= price
|
2789
|
+
// 'expiration': expiration, how many seconds to wait for the condition to be triggered before cancelling the order
|
2790
|
+
},
|
2791
|
+
'settle': market['settleId'],
|
2792
|
+
};
|
2793
|
+
const expiration = this.safeInteger (params, 'expiration');
|
2794
|
+
if (expiration !== undefined) {
|
2795
|
+
request['trigger']['expiration'] = expiration;
|
2796
|
+
params = this.omit (params, 'expiration');
|
2797
|
+
}
|
2798
|
+
if (reduceOnly !== undefined) {
|
2799
|
+
request['initial']['reduce_only'] = reduceOnly;
|
2800
|
+
}
|
2801
|
+
if (timeInForce !== undefined) {
|
2802
|
+
request['initial']['tif'] = timeInForce;
|
2803
|
+
}
|
2804
|
+
} else {
|
2805
|
+
// spot conditional order
|
2806
|
+
const options = this.safeValue (this.options, 'createOrder', {});
|
2807
|
+
let marginType = undefined;
|
2808
|
+
[ marginType, params ] = this.getMarginType (true, params);
|
2809
|
+
const defaultExpiration = this.safeInteger (options, 'expiration');
|
2810
|
+
const expiration = this.safeInteger (params, 'expiration', defaultExpiration);
|
2811
|
+
const rule = (side === 'buy') ? '>=' : '<=';
|
2812
|
+
const triggerPrice = this.safeValue (trigger, 'price', stopPrice);
|
2813
|
+
request = {
|
2814
|
+
'trigger': {
|
2815
|
+
'price': this.priceToPrecision (symbol, triggerPrice),
|
2816
|
+
'rule': rule, // >= triggered when market price larger than or equal to price field, <= triggered when market price less than or equal to price field
|
2817
|
+
'expiration': expiration, // required, how long (in seconds) to wait for the condition to be triggered before cancelling the order
|
2818
|
+
},
|
2819
|
+
'put': {
|
2820
|
+
'type': type,
|
2821
|
+
'side': side,
|
2822
|
+
'price': this.priceToPrecision (symbol, price),
|
2823
|
+
'amount': this.amountToPrecision (symbol, amount),
|
2824
|
+
'account': marginType,
|
2825
|
+
'time_in_force': timeInForce, // gtc, ioc for taker only
|
2826
|
+
},
|
2827
|
+
'market': market['id'],
|
2828
|
+
};
|
2829
|
+
}
|
2830
|
+
methodTail = 'PriceOrders';
|
2831
|
+
}
|
2832
|
+
const method = this.getSupportedMapping (market['type'], {
|
2833
|
+
'spot': 'privateSpotPost' + methodTail,
|
2834
|
+
'margin': 'privateSpotPost' + methodTail,
|
2835
|
+
'swap': 'privateFuturesPostSettle' + methodTail,
|
2836
|
+
'future': 'privateDeliveryPostSettle' + methodTail,
|
2837
|
+
});
|
2838
|
+
const response = await this[method] (this.deepExtend (request, params));
|
2839
|
+
//
|
2840
|
+
// spot
|
2841
|
+
//
|
2842
|
+
// {
|
2843
|
+
// "id": "95282841887",
|
2844
|
+
// "text": "apiv4",
|
2845
|
+
// "create_time": "1637383156",
|
2846
|
+
// "update_time": "1637383156",
|
2847
|
+
// "create_time_ms": 1637383156017,
|
2848
|
+
// "update_time_ms": 1637383156017,
|
2849
|
+
// "status": "open",
|
2850
|
+
// "currency_pair": "ETH_USDT",
|
2851
|
+
// "type": "limit",
|
2852
|
+
// "account": "spot",
|
2853
|
+
// "side": "buy",
|
2854
|
+
// "amount": "0.01",
|
2855
|
+
// "price": "3500",
|
2856
|
+
// "time_in_force": "gtc",
|
2857
|
+
// "iceberg": "0",
|
2858
|
+
// "left": "0.01",
|
2859
|
+
// "fill_price": "0",
|
2860
|
+
// "filled_total": "0",
|
2861
|
+
// "fee": "0",
|
2862
|
+
// "fee_currency": "ETH",
|
2863
|
+
// "point_fee": "0",
|
2864
|
+
// "gt_fee": "0",
|
2865
|
+
// "gt_discount": false,
|
2866
|
+
// "rebated_fee": "0",
|
2867
|
+
// "rebated_fee_currency": "USDT"
|
2868
|
+
// }
|
2869
|
+
//
|
2870
|
+
// spot conditional
|
2871
|
+
//
|
2872
|
+
// {"id": 5891843}
|
2873
|
+
//
|
2874
|
+
// future and perpetual swaps
|
2875
|
+
//
|
2876
|
+
// {
|
2877
|
+
// "id": 95938572327,
|
2878
|
+
// "contract": "ETH_USDT",
|
2879
|
+
// "mkfr": "0",
|
2880
|
+
// "tkfr": "0.0005",
|
2881
|
+
// "tif": "gtc",
|
2882
|
+
// "is_reduce_only": false,
|
2883
|
+
// "create_time": 1637384600.08,
|
2884
|
+
// "price": "3000",
|
2885
|
+
// "size": 1,
|
2886
|
+
// "refr": "0",
|
2887
|
+
// "left": 1,
|
2888
|
+
// "text": "api",
|
2889
|
+
// "fill_price": "0",
|
2890
|
+
// "user": 2436035,
|
2891
|
+
// "status": "open",
|
2892
|
+
// "is_liq": false,
|
2893
|
+
// "refu": 0,
|
2894
|
+
// "is_close": false,
|
2895
|
+
// "iceberg": 0
|
2896
|
+
// }
|
2897
|
+
//
|
2898
|
+
// futures and perpetual swaps conditionals
|
2899
|
+
//
|
2900
|
+
// {"id": 7615567}
|
2901
|
+
//
|
2902
|
+
return this.parseOrder (response, market);
|
2903
|
+
}
|
2904
|
+
|
2905
|
+
parseOrderStatus (status) {
|
2906
|
+
const statuses = {
|
2907
|
+
'_new': 'open',
|
2908
|
+
'filled': 'closed',
|
2909
|
+
'cancelled': 'canceled',
|
2910
|
+
'liquidated': 'closed',
|
2911
|
+
};
|
2912
|
+
return this.safeString (statuses, status, status);
|
2913
|
+
}
|
2914
|
+
|
2915
|
+
parseOrder (order, market = undefined) {
|
2916
|
+
//
|
2917
|
+
// SPOT
|
2918
|
+
// createOrder/cancelOrder/fetchOrder
|
2919
|
+
//
|
2920
|
+
// {
|
2921
|
+
// "id": "62364648575",
|
2922
|
+
// "text": "apiv4",
|
2923
|
+
// "create_time": "1626354834",
|
2924
|
+
// "update_time": "1626354834",
|
2925
|
+
// "create_time_ms": "1626354833544",
|
2926
|
+
// "update_time_ms": "1626354833544",
|
2927
|
+
// "status": "open",
|
2928
|
+
// "currency_pair": "BTC_USDT",
|
2929
|
+
// "type": "limit",
|
2930
|
+
// "account": "spot",
|
2931
|
+
// "side": "buy",
|
2932
|
+
// "amount": "0.0001",
|
2933
|
+
// "price": "30000",
|
2934
|
+
// "time_in_force": "gtc",
|
2935
|
+
// "iceberg": "0",
|
2936
|
+
// "left": "0.0001",
|
2937
|
+
// "fill_price": "0",
|
2938
|
+
// "filled_total": "0",
|
2939
|
+
// "fee": "0",
|
2940
|
+
// "fee_currency": "BTC",
|
2941
|
+
// "point_fee": "0",
|
2942
|
+
// "gt_fee": "0",
|
2943
|
+
// "gt_discount": true,
|
2944
|
+
// "rebated_fee": "0",
|
2945
|
+
// "rebated_fee_currency": "USDT"
|
2946
|
+
// }
|
2947
|
+
//
|
2948
|
+
// SPOT TRIGGER ORDERS
|
2949
|
+
// createOrder
|
2950
|
+
//
|
2951
|
+
// {
|
2952
|
+
// "id": 12604556
|
2953
|
+
// }
|
2954
|
+
//
|
2955
|
+
// fetchOrder/cancelOrder
|
2956
|
+
//
|
2957
|
+
// {
|
2958
|
+
// "market": "ADA_USDT",
|
2959
|
+
// "user": 6392049,
|
2960
|
+
// "trigger": {
|
2961
|
+
// "price": "1.08", // stopPrice
|
2962
|
+
// "rule": "\u003e=",
|
2963
|
+
// "expiration": 86400
|
2964
|
+
// },
|
2965
|
+
// "put": {
|
2966
|
+
// "type": "limit",
|
2967
|
+
// "side": "buy",
|
2968
|
+
// "price": "1.08", // order price
|
2969
|
+
// "amount": "1.00000000000000000000",
|
2970
|
+
// "account": "normal",
|
2971
|
+
// "time_in_force": "gtc"
|
2972
|
+
// },
|
2973
|
+
// "id": 71639298,
|
2974
|
+
// "ctime": 1643945985,
|
2975
|
+
// "status": "open"
|
2976
|
+
// }
|
2977
|
+
//
|
2978
|
+
// FUTURE AND SWAP
|
2979
|
+
// createOrder/cancelOrder/fetchOrder
|
2980
|
+
//
|
2981
|
+
// {
|
2982
|
+
// "id": 123028481731,
|
2983
|
+
// "contract": "ADA_USDT",
|
2984
|
+
// "mkfr": "-0.00005",
|
2985
|
+
// "tkfr": "0.00048",
|
2986
|
+
// "tif": "ioc",
|
2987
|
+
// "is_reduce_only": false,
|
2988
|
+
// "create_time": 1643950262.68,
|
2989
|
+
// "finish_time": 1643950262.68,
|
2990
|
+
// "price": "0",
|
2991
|
+
// "size": 1,
|
2992
|
+
// "refr": "0",
|
2993
|
+
// "left":0,
|
2994
|
+
// "text": "api",
|
2995
|
+
// "fill_price": "1.05273",
|
2996
|
+
// "user":6329238,
|
2997
|
+
// "finish_as": "filled",
|
2998
|
+
// "status": "finished",
|
2999
|
+
// "is_liq": false,
|
3000
|
+
// "refu":0,
|
3001
|
+
// "is_close": false,
|
3002
|
+
// "iceberg": 0
|
3003
|
+
// }
|
3004
|
+
//
|
3005
|
+
// TRIGGER ORDERS (FUTURE AND SWAP)
|
3006
|
+
// createOrder
|
3007
|
+
//
|
3008
|
+
// {
|
3009
|
+
// "id": 12604556
|
3010
|
+
// }
|
3011
|
+
//
|
3012
|
+
// fetchOrder/cancelOrder
|
3013
|
+
//
|
3014
|
+
// {
|
3015
|
+
// "user": 6320300,
|
3016
|
+
// "trigger": {
|
3017
|
+
// "strategy_type": 0,
|
3018
|
+
// "price_type": 0,
|
3019
|
+
// "price": "1.03", // stopPrice
|
3020
|
+
// "rule": 2,
|
3021
|
+
// "expiration": 0
|
3022
|
+
// },
|
3023
|
+
// "initial": {
|
3024
|
+
// "contract": "ADA_USDT",
|
3025
|
+
// "size": -1,
|
3026
|
+
// "price": "1.02",
|
3027
|
+
// "tif": "gtc",
|
3028
|
+
// "text": "",
|
3029
|
+
// "iceberg": 0,
|
3030
|
+
// "is_close": false,
|
3031
|
+
// "is_reduce_only": false,
|
3032
|
+
// "auto_size": ""
|
3033
|
+
// },
|
3034
|
+
// "id": 126393906,
|
3035
|
+
// "trade_id": 0,
|
3036
|
+
// "status": "open",
|
3037
|
+
// "reason": "",
|
3038
|
+
// "create_time": 1643953482,
|
3039
|
+
// "finish_time": 1643953482,
|
3040
|
+
// "is_stop_order": false,
|
3041
|
+
// "stop_trigger": {
|
3042
|
+
// "rule": 0,
|
3043
|
+
// "trigger_price": "",
|
3044
|
+
// "order_price": ""
|
3045
|
+
// },
|
3046
|
+
// "me_order_id": 0,
|
3047
|
+
// "order_type": ""
|
3048
|
+
// }
|
3049
|
+
//
|
3050
|
+
const put = this.safeValue2 (order, 'put', 'initial');
|
3051
|
+
const trigger = this.safeValue (order, 'trigger');
|
3052
|
+
let contract = this.safeString (put, 'contract');
|
3053
|
+
let type = this.safeString (put, 'type');
|
3054
|
+
let timeInForce = this.safeStringUpper2 (put, 'time_in_force', 'tif');
|
3055
|
+
let amount = this.safeString2 (put, 'amount', 'size');
|
3056
|
+
let side = this.safeString (put, 'side');
|
3057
|
+
let price = this.safeString (put, 'price');
|
3058
|
+
contract = this.safeString (order, 'contract', contract);
|
3059
|
+
type = this.safeString (order, 'type', type);
|
3060
|
+
timeInForce = this.safeStringUpper2 (order, 'time_in_force', 'tif', timeInForce);
|
3061
|
+
if (timeInForce === 'POC') {
|
3062
|
+
timeInForce = 'PO';
|
3063
|
+
}
|
3064
|
+
const postOnly = (timeInForce === 'PO');
|
3065
|
+
amount = this.safeString2 (order, 'amount', 'size', amount);
|
3066
|
+
side = this.safeString (order, 'side', side);
|
3067
|
+
price = this.safeString (order, 'price', price);
|
3068
|
+
let remaining = this.safeString (order, 'left');
|
3069
|
+
let filled = Precise.stringSub (amount, remaining);
|
3070
|
+
let cost = this.safeString (order, 'filled_total');
|
3071
|
+
let rawStatus = undefined;
|
3072
|
+
let average = undefined;
|
3073
|
+
if (put) {
|
3074
|
+
remaining = amount;
|
3075
|
+
filled = '0';
|
3076
|
+
cost = '0';
|
3077
|
+
}
|
3078
|
+
if (contract) {
|
3079
|
+
const isMarketOrder = Precise.stringEquals (price, '0') && (timeInForce === 'IOC');
|
3080
|
+
type = isMarketOrder ? 'market' : 'limit';
|
3081
|
+
side = Precise.stringGt (amount, '0') ? 'buy' : 'sell';
|
3082
|
+
rawStatus = this.safeString (order, 'finish_as', 'open');
|
3083
|
+
average = this.safeNumber (order, 'fill_price');
|
3084
|
+
} else {
|
3085
|
+
rawStatus = this.safeString (order, 'status');
|
3086
|
+
}
|
3087
|
+
let timestamp = this.safeInteger (order, 'create_time_ms');
|
3088
|
+
if (timestamp === undefined) {
|
3089
|
+
timestamp = this.safeTimestamp2 (order, 'create_time', 'ctime');
|
3090
|
+
}
|
3091
|
+
let lastTradeTimestamp = this.safeInteger (order, 'update_time_ms');
|
3092
|
+
if (lastTradeTimestamp === undefined) {
|
3093
|
+
lastTradeTimestamp = this.safeTimestamp2 (order, 'update_time', 'finish_time');
|
3094
|
+
}
|
3095
|
+
const exchangeSymbol = this.safeString2 (order, 'currency_pair', 'market', contract);
|
3096
|
+
// Everything below this(above return) is related to fees
|
3097
|
+
const fees = [];
|
3098
|
+
const gtFee = this.safeString (order, 'gt_fee');
|
3099
|
+
if (gtFee) {
|
3100
|
+
fees.push ({
|
3101
|
+
'currency': 'GT',
|
3102
|
+
'cost': gtFee,
|
3103
|
+
});
|
3104
|
+
}
|
3105
|
+
const fee = this.safeString (order, 'fee');
|
3106
|
+
if (fee) {
|
3107
|
+
fees.push ({
|
3108
|
+
'currency': this.safeCurrencyCode (this.safeString (order, 'fee_currency')),
|
3109
|
+
'cost': fee,
|
3110
|
+
});
|
3111
|
+
}
|
3112
|
+
const rebate = this.safeString (order, 'rebated_fee');
|
3113
|
+
if (rebate) {
|
3114
|
+
fees.push ({
|
3115
|
+
'currency': this.safeCurrencyCode (this.safeString (order, 'rebated_fee_currency')),
|
3116
|
+
'cost': Precise.stringNeg (rebate),
|
3117
|
+
});
|
3118
|
+
}
|
3119
|
+
const numFeeCurrencies = fees.length;
|
3120
|
+
const multipleFeeCurrencies = numFeeCurrencies > 1;
|
3121
|
+
const status = this.parseOrderStatus (rawStatus);
|
3122
|
+
return this.safeOrder ({
|
3123
|
+
'id': this.safeString (order, 'id'),
|
3124
|
+
'clientOrderId': this.safeString (order, 'text'),
|
3125
|
+
'timestamp': timestamp,
|
3126
|
+
'datetime': this.iso8601 (timestamp),
|
3127
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
3128
|
+
'status': status,
|
3129
|
+
'symbol': this.safeSymbol (exchangeSymbol),
|
3130
|
+
'type': type,
|
3131
|
+
'timeInForce': timeInForce,
|
3132
|
+
'postOnly': postOnly,
|
3133
|
+
'side': side,
|
3134
|
+
'price': this.parseNumber (price),
|
3135
|
+
'stopPrice': this.safeNumber (trigger, 'price'),
|
3136
|
+
'average': average,
|
3137
|
+
'amount': this.parseNumber (Precise.stringAbs (amount)),
|
3138
|
+
'cost': Precise.stringAbs (cost),
|
3139
|
+
'filled': this.parseNumber (Precise.stringAbs (filled)),
|
3140
|
+
'remaining': this.parseNumber (Precise.stringAbs (remaining)),
|
3141
|
+
'fee': multipleFeeCurrencies ? undefined : this.safeValue (fees, 0),
|
3142
|
+
'fees': multipleFeeCurrencies ? fees : [],
|
3143
|
+
'trades': undefined,
|
3144
|
+
'info': order,
|
3145
|
+
}, market);
|
3146
|
+
}
|
3147
|
+
|
3148
|
+
async createReduceOnlyOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
3149
|
+
const request = {
|
3150
|
+
'reduceOnly': true,
|
3151
|
+
};
|
3152
|
+
return await this.createOrder (symbol, type, side, amount, price, this.extend (request, params));
|
3153
|
+
}
|
3154
|
+
|
3155
|
+
async fetchOrder (id, symbol = undefined, params = {}) {
|
3156
|
+
/**
|
3157
|
+
* @method
|
3158
|
+
* @name gateio#fetchOrder
|
3159
|
+
* @description Retrieves information on an order
|
3160
|
+
* @param {str} id Order id
|
3161
|
+
* @param {str} symbol Unified market symbol
|
3162
|
+
* @param {dict} params Parameters specified by the exchange api
|
3163
|
+
* @param {bool} params.stop True if the order being fetched is a trigger order
|
3164
|
+
* @param {str} params.marginType 'cross' or 'isolated' - marginType for margin trading if not provided this.options['defaultMarginType'] is used
|
3165
|
+
* @param {str} params.type 'spot', 'swap', or 'future', if not provided this.options['defaultMarginType'] is used
|
3166
|
+
* @param {str} params.settle 'btc' or 'usdt' - settle currency for perpetual swap and future - market settle currency is used if symbol !== undefined, default="usdt" for swap and "btc" for future
|
3167
|
+
* @returns An [order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure}
|
3168
|
+
*/
|
3169
|
+
await this.loadMarkets ();
|
3170
|
+
const stop = this.safeValue2 (params, 'is_stop_order', 'stop', false);
|
3171
|
+
params = this.omit (params, [ 'is_stop_order', 'stop' ]);
|
3172
|
+
let clientOrderId = this.safeString2 (params, 'text', 'clientOrderId');
|
3173
|
+
let orderId = id;
|
3174
|
+
if (clientOrderId !== undefined) {
|
3175
|
+
params = this.omit (params, [ 'text', 'clientOrderId' ]);
|
3176
|
+
if (clientOrderId[0] !== 't') {
|
3177
|
+
clientOrderId = 't-' + clientOrderId;
|
3178
|
+
}
|
3179
|
+
orderId = clientOrderId;
|
3180
|
+
}
|
3181
|
+
const request = {
|
3182
|
+
'order_id': orderId,
|
3183
|
+
};
|
3184
|
+
let market = undefined;
|
3185
|
+
let settle = undefined;
|
3186
|
+
let type = undefined;
|
3187
|
+
if (symbol !== undefined) {
|
3188
|
+
market = this.market (symbol);
|
3189
|
+
if (market['spot']) {
|
3190
|
+
request['currency_pair'] = market['id'];
|
3191
|
+
} else {
|
3192
|
+
settle = market['settle'];
|
3193
|
+
}
|
3194
|
+
}
|
3195
|
+
[ type, params ] = this.handleMarketTypeAndParams ('fetchOrder', market, params);
|
3196
|
+
if (!stop && type === 'spot' && symbol === undefined) {
|
3197
|
+
// Symbol not required for stop orders
|
3198
|
+
throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument for spot orders');
|
3199
|
+
}
|
3200
|
+
const swap = type === 'swap';
|
3201
|
+
if (swap || type === 'future') {
|
3202
|
+
if (settle === undefined) {
|
3203
|
+
const defaultSettle = swap ? 'usdt' : 'btc';
|
3204
|
+
settle = this.safeStringLower (params, 'settle', defaultSettle);
|
3205
|
+
params = this.omit (params, 'settle');
|
3206
|
+
}
|
3207
|
+
request['settle'] = settle;
|
3208
|
+
} else {
|
3209
|
+
let marginType = undefined;
|
3210
|
+
[ marginType, params ] = this.getMarginType (stop, params);
|
3211
|
+
request['account'] = marginType;
|
3212
|
+
}
|
3213
|
+
let method = undefined;
|
3214
|
+
if (stop) {
|
3215
|
+
method = this.getSupportedMapping (type, {
|
3216
|
+
'spot': 'privateSpotGetPriceOrdersOrderId',
|
3217
|
+
'margin': 'privateSpotGetPriceOrdersOrderId',
|
3218
|
+
'swap': 'privateFuturesGetSettlePriceOrdersOrderId',
|
3219
|
+
'future': 'privateDeliveryGetSettlePriceOrdersOrderId',
|
3220
|
+
});
|
3221
|
+
} else {
|
3222
|
+
method = this.getSupportedMapping (type, {
|
3223
|
+
'spot': 'privateSpotGetOrdersOrderId',
|
3224
|
+
'margin': 'privateSpotGetOrdersOrderId',
|
3225
|
+
'swap': 'privateFuturesGetSettleOrdersOrderId',
|
3226
|
+
'future': 'privateDeliveryGetSettleOrdersOrderId',
|
3227
|
+
});
|
3228
|
+
}
|
3229
|
+
const response = await this[method] (this.extend (request, params));
|
3230
|
+
return this.parseOrder (response, market);
|
3231
|
+
}
|
3232
|
+
|
3233
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
3234
|
+
/**
|
3235
|
+
* @description fetches all open orders
|
3236
|
+
* @param {str} symbol Unified market symbol
|
3237
|
+
* @param {int} since earliest time in ms for orders in the response
|
3238
|
+
* @param {int} limit max number of order structures to return
|
3239
|
+
* @param {dict} params exchange specific params
|
3240
|
+
* @param {str} params.type spot, margin, swap or future, if not provided this.options['defaultType'] is used
|
3241
|
+
* @param {str} params.marginType 'cross' or 'isolated' - marginType for type='margin', if not provided this.options['defaultMarginType'] is used
|
3242
|
+
* @returns An array of order structures
|
3243
|
+
*/
|
3244
|
+
await this.loadMarkets ();
|
3245
|
+
let type = undefined;
|
3246
|
+
[ type, params ] = this.handleMarketTypeAndParams ('fetchOpenOrders', undefined, params);
|
3247
|
+
if (symbol === undefined && (type === 'spot') || type === 'margin' || type === 'cross_margin') {
|
3248
|
+
const request = {
|
3249
|
+
// 'page': 1,
|
3250
|
+
// 'limit': limit,
|
3251
|
+
'account': type, // spot/margin (default), cross_margin
|
3252
|
+
};
|
3253
|
+
if (limit !== undefined) {
|
3254
|
+
request['limit'] = limit;
|
3255
|
+
}
|
3256
|
+
const response = await this.privateSpotGetOpenOrders (this.extend (request, params));
|
3257
|
+
//
|
3258
|
+
// [
|
3259
|
+
// {
|
3260
|
+
// "currency_pair": "ETH_BTC",
|
3261
|
+
// "total": 1,
|
3262
|
+
// "orders": [
|
3263
|
+
// {
|
3264
|
+
// "id": "12332324",
|
3265
|
+
// "text": "t-123456",
|
3266
|
+
// "create_time": "1548000000",
|
3267
|
+
// "update_time": "1548000100",
|
3268
|
+
// "currency_pair": "ETH_BTC",
|
3269
|
+
// "status": "open",
|
3270
|
+
// "type": "limit",
|
3271
|
+
// "account": "spot",
|
3272
|
+
// "side": "buy",
|
3273
|
+
// "amount": "1",
|
3274
|
+
// "price": "5.00032",
|
3275
|
+
// "time_in_force": "gtc",
|
3276
|
+
// "left": "0.5",
|
3277
|
+
// "filled_total": "2.50016",
|
3278
|
+
// "fee": "0.005",
|
3279
|
+
// "fee_currency": "ETH",
|
3280
|
+
// "point_fee": "0",
|
3281
|
+
// "gt_fee": "0",
|
3282
|
+
// "gt_discount": false,
|
3283
|
+
// "rebated_fee": "0",
|
3284
|
+
// "rebated_fee_currency": "BTC"
|
3285
|
+
// }
|
3286
|
+
// ]
|
3287
|
+
// },
|
3288
|
+
// ...
|
3289
|
+
// ]
|
3290
|
+
//
|
3291
|
+
// price_orders
|
3292
|
+
//
|
3293
|
+
// [
|
3294
|
+
// {
|
3295
|
+
// "market": "ADA_USDT",
|
3296
|
+
// "user": 6693577,
|
3297
|
+
// "trigger": {
|
3298
|
+
// "price": "0.9",
|
3299
|
+
// "rule": "\u003c=",
|
3300
|
+
// "expiration": 86400
|
3301
|
+
// },
|
3302
|
+
// "put": {
|
3303
|
+
// "type": "limit",
|
3304
|
+
// "side": "sell",
|
3305
|
+
// "price": "0.9",
|
3306
|
+
// "amount": "2.00000000000000000000",
|
3307
|
+
// "account": "margin",
|
3308
|
+
// "time_in_force": "gtc"
|
3309
|
+
// },
|
3310
|
+
// "id": 8308730,
|
3311
|
+
// "ctime": 1650434238,
|
3312
|
+
// "status": "open"
|
3313
|
+
// }
|
3314
|
+
// ]
|
3315
|
+
//
|
3316
|
+
let allOrders = [];
|
3317
|
+
for (let i = 0; i < response.length; i++) {
|
3318
|
+
const entry = response[i];
|
3319
|
+
const orders = this.safeValue (entry, 'orders', []);
|
3320
|
+
const parsed = this.parseOrders (orders, undefined, since, limit);
|
3321
|
+
allOrders = this.arrayConcat (allOrders, parsed);
|
3322
|
+
}
|
3323
|
+
return this.filterBySinceLimit (allOrders, since, limit);
|
3324
|
+
}
|
3325
|
+
return await this.fetchOrdersByStatus ('open', symbol, since, limit, params);
|
3326
|
+
}
|
3327
|
+
|
3328
|
+
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
3329
|
+
return await this.fetchOrdersByStatus ('finished', symbol, since, limit, params);
|
3330
|
+
}
|
3331
|
+
|
3332
|
+
async fetchOrdersByStatus (status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
3333
|
+
if (symbol === undefined) {
|
3334
|
+
throw new ArgumentsRequired (this.id + ' fetchOrdersByStatus() requires a symbol argument');
|
3335
|
+
}
|
3336
|
+
await this.loadMarkets ();
|
3337
|
+
const market = this.market (symbol);
|
3338
|
+
const request = this.prepareRequest (market);
|
3339
|
+
request['status'] = status;
|
3340
|
+
if (limit !== undefined) {
|
3341
|
+
request['limit'] = limit;
|
3342
|
+
}
|
3343
|
+
if (since !== undefined && (market['spot'] || market['margin'])) {
|
3344
|
+
request['from'] = parseInt (since / 1000);
|
3345
|
+
}
|
3346
|
+
const method = this.getSupportedMapping (market['type'], {
|
3347
|
+
'spot': 'privateSpotGetOrders',
|
3348
|
+
'margin': 'privateSpotGetOrders',
|
3349
|
+
'swap': 'privateFuturesGetSettleOrders',
|
3350
|
+
'future': 'privateDeliveryGetSettleOrders',
|
3351
|
+
});
|
3352
|
+
if (market['type'] === 'margin' || market['type'] === 'cross_margin') {
|
3353
|
+
request['account'] = market['type'];
|
3354
|
+
}
|
3355
|
+
const response = await this[method] (this.extend (request, params));
|
3356
|
+
//
|
3357
|
+
// SPOT
|
3358
|
+
//
|
3359
|
+
// {
|
3360
|
+
// "id": "8834234273",
|
3361
|
+
// "text": "3",
|
3362
|
+
// "create_time": "1635406193",
|
3363
|
+
// "update_time": "1635406193",
|
3364
|
+
// "create_time_ms": 1635406193361,
|
3365
|
+
// "update_time_ms": 1635406193361,
|
3366
|
+
// "status": "closed",
|
3367
|
+
// "currency_pair": "BTC_USDT",
|
3368
|
+
// "type": "limit",
|
3369
|
+
// "account": "spot",
|
3370
|
+
// "side": "sell",
|
3371
|
+
// "amount": "0.0002",
|
3372
|
+
// "price": "58904.01",
|
3373
|
+
// "time_in_force": "gtc",
|
3374
|
+
// "iceberg": "0",
|
3375
|
+
// "left": "0.0000",
|
3376
|
+
// "fill_price": "11.790516",
|
3377
|
+
// "filled_total": "11.790516",
|
3378
|
+
// "fee": "0.023581032",
|
3379
|
+
// "fee_currency": "USDT",
|
3380
|
+
// "point_fee": "0",
|
3381
|
+
// "gt_fee": "0",
|
3382
|
+
// "gt_discount": false,
|
3383
|
+
// "rebated_fee_currency": "BTC"
|
3384
|
+
// }
|
3385
|
+
//
|
3386
|
+
// Perpetual Swap
|
3387
|
+
//
|
3388
|
+
// {
|
3389
|
+
// "status": "finished",
|
3390
|
+
// "size": -1,
|
3391
|
+
// "left": 0,
|
3392
|
+
// "id": 82750739203,
|
3393
|
+
// "is_liq": false,
|
3394
|
+
// "is_close": false,
|
3395
|
+
// "contract": "BTC_USDT",
|
3396
|
+
// "text": "web",
|
3397
|
+
// "fill_price": "60721.3",
|
3398
|
+
// "finish_as": "filled",
|
3399
|
+
// "iceberg": 0,
|
3400
|
+
// "tif": "ioc",
|
3401
|
+
// "is_reduce_only": true,
|
3402
|
+
// "create_time": 1635403475.412,
|
3403
|
+
// "finish_time": 1635403475.4127,
|
3404
|
+
// "price": "0"
|
3405
|
+
// }
|
3406
|
+
//
|
3407
|
+
return this.parseOrders (response, market, since, limit);
|
3408
|
+
}
|
3409
|
+
|
3410
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
3411
|
+
/**
|
3412
|
+
* @method
|
3413
|
+
* @name gateio#cancelOrder
|
3414
|
+
* @description Cancels an open order
|
3415
|
+
* @param {str} id Order id
|
3416
|
+
* @param {str} symbol Unified market symbol
|
3417
|
+
* @param {dict} params Parameters specified by the exchange api
|
3418
|
+
* @param {bool} params.stop True if the order to be cancelled is a trigger order
|
3419
|
+
* @returns An [order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure}
|
3420
|
+
*/
|
3421
|
+
if (symbol === undefined) {
|
3422
|
+
throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
|
3423
|
+
}
|
3424
|
+
await this.loadMarkets ();
|
3425
|
+
const market = this.market (symbol);
|
3426
|
+
const request = {
|
3427
|
+
'order_id': id,
|
3428
|
+
};
|
3429
|
+
if (market['contract']) {
|
3430
|
+
request['settle'] = market['settleId'];
|
3431
|
+
} else {
|
3432
|
+
request['currency_pair'] = market['id'];
|
3433
|
+
}
|
3434
|
+
const stop = this.safeValue2 (params, 'is_stop_order', 'stop', false);
|
3435
|
+
params = this.omit (params, [ 'is_stop_order', 'stop' ]);
|
3436
|
+
const pathMiddle = stop ? 'Price' : '';
|
3437
|
+
const method = this.getSupportedMapping (market['type'], {
|
3438
|
+
'spot': 'privateSpotDelete' + pathMiddle + 'OrdersOrderId',
|
3439
|
+
'margin': 'privateSpotDelete' + pathMiddle + 'OrdersOrderId',
|
3440
|
+
'swap': 'privateFuturesDeleteSettle' + pathMiddle + 'OrdersOrderId',
|
3441
|
+
'future': 'privateDeliveryDeleteSettle' + pathMiddle + 'OrdersOrderId',
|
3442
|
+
});
|
3443
|
+
const response = await this[method] (this.extend (request, params));
|
3444
|
+
//
|
3445
|
+
// spot
|
3446
|
+
//
|
3447
|
+
// {
|
3448
|
+
// "id": "95282841887",
|
3449
|
+
// "text": "apiv4",
|
3450
|
+
// "create_time": "1637383156",
|
3451
|
+
// "update_time": "1637383235",
|
3452
|
+
// "create_time_ms": 1637383156017,
|
3453
|
+
// "update_time_ms": 1637383235085,
|
3454
|
+
// "status": "cancelled",
|
3455
|
+
// "currency_pair": "ETH_USDT",
|
3456
|
+
// "type": "limit",
|
3457
|
+
// "account": "spot",
|
3458
|
+
// "side": "buy",
|
3459
|
+
// "amount": "0.01",
|
3460
|
+
// "price": "3500",
|
3461
|
+
// "time_in_force": "gtc",
|
3462
|
+
// "iceberg": "0",
|
3463
|
+
// "left": "0.01",
|
3464
|
+
// "fill_price": "0",
|
3465
|
+
// "filled_total": "0",
|
3466
|
+
// "fee": "0",
|
3467
|
+
// "fee_currency": "ETH",
|
3468
|
+
// "point_fee": "0",
|
3469
|
+
// "gt_fee": "0",
|
3470
|
+
// "gt_discount": false,
|
3471
|
+
// "rebated_fee": "0",
|
3472
|
+
// "rebated_fee_currency": "USDT"
|
3473
|
+
// }
|
3474
|
+
//
|
3475
|
+
// spot conditional
|
3476
|
+
//
|
3477
|
+
// {
|
3478
|
+
// "market": "ETH_USDT",
|
3479
|
+
// "user": 2436035,
|
3480
|
+
// "trigger": {
|
3481
|
+
// "price": "3500",
|
3482
|
+
// "rule": "\u003c=",
|
3483
|
+
// "expiration": 86400
|
3484
|
+
// },
|
3485
|
+
// "put": {
|
3486
|
+
// "type": "limit",
|
3487
|
+
// "side": "buy",
|
3488
|
+
// "price": "3500",
|
3489
|
+
// "amount": "0.01000000000000000000",
|
3490
|
+
// "account": "normal",
|
3491
|
+
// "time_in_force": "gtc"
|
3492
|
+
// },
|
3493
|
+
// "id": 5891843,
|
3494
|
+
// "ctime": 1637382379,
|
3495
|
+
// "ftime": 1637382673,
|
3496
|
+
// "status": "canceled"
|
3497
|
+
// }
|
3498
|
+
//
|
3499
|
+
// perpetual swaps
|
3500
|
+
//
|
3501
|
+
// {
|
3502
|
+
// id: "82241928192",
|
3503
|
+
// contract: "BTC_USDT",
|
3504
|
+
// mkfr: "0",
|
3505
|
+
// tkfr: "0.0005",
|
3506
|
+
// tif: "gtc",
|
3507
|
+
// is_reduce_only: false,
|
3508
|
+
// create_time: "1635196145.06",
|
3509
|
+
// finish_time: "1635196233.396",
|
3510
|
+
// price: "61000",
|
3511
|
+
// size: "4",
|
3512
|
+
// refr: "0",
|
3513
|
+
// left: "4",
|
3514
|
+
// text: "web",
|
3515
|
+
// fill_price: "0",
|
3516
|
+
// user: "6693577",
|
3517
|
+
// finish_as: "cancelled",
|
3518
|
+
// status: "finished",
|
3519
|
+
// is_liq: false,
|
3520
|
+
// refu: "0",
|
3521
|
+
// is_close: false,
|
3522
|
+
// iceberg: "0",
|
3523
|
+
// }
|
3524
|
+
//
|
3525
|
+
return this.parseOrder (response, market);
|
3526
|
+
}
|
3527
|
+
|
3528
|
+
async cancelAllOrders (symbol = undefined, params = {}) {
|
3529
|
+
await this.loadMarkets ();
|
3530
|
+
let request = {};
|
3531
|
+
let market = undefined;
|
3532
|
+
if (symbol !== undefined) {
|
3533
|
+
market = this.market (symbol);
|
3534
|
+
request = this.prepareRequest (market);
|
3535
|
+
}
|
3536
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('cancelAllOrders', market, params);
|
3537
|
+
const swap = type === 'swap';
|
3538
|
+
const future = type === 'future';
|
3539
|
+
if (symbol === undefined && (swap || future)) {
|
3540
|
+
const defaultSettle = swap ? 'usdt' : 'btc';
|
3541
|
+
const settle = this.safeStringLower (params, 'settle', defaultSettle);
|
3542
|
+
request['settle'] = settle;
|
3543
|
+
}
|
3544
|
+
const method = this.getSupportedMapping (type, {
|
3545
|
+
'spot': 'privateSpotDeleteOrders',
|
3546
|
+
'margin': 'privateSpotDeleteOrders',
|
3547
|
+
'swap': 'privateFuturesDeleteSettleOrders',
|
3548
|
+
'future': 'privateDeliveryDeleteSettleOrders',
|
3549
|
+
});
|
3550
|
+
const response = await this[method] (this.extend (request, query));
|
3551
|
+
//
|
3552
|
+
// [
|
3553
|
+
// {
|
3554
|
+
// "id": 139797004085,
|
3555
|
+
// "contract": "ADA_USDT",
|
3556
|
+
// "mkfr": "0",
|
3557
|
+
// "tkfr": "0.0005",
|
3558
|
+
// "tif": "gtc",
|
3559
|
+
// "is_reduce_only": false,
|
3560
|
+
// "create_time": 1647911169.343,
|
3561
|
+
// "finish_time": 1647911226.849,
|
3562
|
+
// "price": "0.8",
|
3563
|
+
// "size": 1,
|
3564
|
+
// "refr": "0.3",
|
3565
|
+
// "left": 1,
|
3566
|
+
// "text": "api",
|
3567
|
+
// "fill_price": "0",
|
3568
|
+
// "user": 6693577,
|
3569
|
+
// "finish_as": "cancelled",
|
3570
|
+
// "status": "finished",
|
3571
|
+
// "is_liq": false,
|
3572
|
+
// "refu": 2436035,
|
3573
|
+
// "is_close": false,
|
3574
|
+
// "iceberg": 0
|
3575
|
+
// }
|
3576
|
+
// ...
|
3577
|
+
// ]
|
3578
|
+
//
|
3579
|
+
return this.parseOrders (response, market);
|
3580
|
+
}
|
3581
|
+
|
3582
|
+
async transfer (code, amount, fromAccount, toAccount, params = {}) {
|
3583
|
+
/**
|
3584
|
+
* @method
|
3585
|
+
* @name gateio#transfer
|
3586
|
+
* @description makes internal transfers of funds between accounts on the same exchange
|
3587
|
+
* @param {str} code unified currency code for currency being transferred
|
3588
|
+
* @param {float} amount the amount of currency to transfer
|
3589
|
+
* @param {str} fromAccount the account to transfer currency from
|
3590
|
+
* @param {str} toAccount the account to transfer currency to
|
3591
|
+
* @param {dict} params Exchange specific parameters
|
3592
|
+
* @param {dict} params.symbol Unified market symbol *required for type == margin*
|
3593
|
+
* @returns A [transfer structure]{@link https://docs.ccxt.com/en/latest/manual.html#transfer-structure}
|
3594
|
+
*/
|
3595
|
+
await this.loadMarkets ();
|
3596
|
+
const currency = this.currency (code);
|
3597
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType', {});
|
3598
|
+
const fromId = this.safeString (accountsByType, fromAccount, fromAccount);
|
3599
|
+
const toId = this.safeString (accountsByType, toAccount, toAccount);
|
3600
|
+
if (fromId === undefined) {
|
3601
|
+
const keys = Object.keys (accountsByType);
|
3602
|
+
throw new ExchangeError (this.id + ' transfer() fromAccount must be one of ' + keys.join (', '));
|
3603
|
+
}
|
3604
|
+
if (toId === undefined) {
|
3605
|
+
const keys = Object.keys (accountsByType);
|
3606
|
+
throw new ExchangeError (this.id + ' transfer() toAccount must be one of ' + keys.join (', '));
|
3607
|
+
}
|
3608
|
+
const truncated = this.currencyToPrecision (code, amount);
|
3609
|
+
const request = {
|
3610
|
+
'currency': currency['id'],
|
3611
|
+
'from': fromId,
|
3612
|
+
'to': toId,
|
3613
|
+
'amount': truncated,
|
3614
|
+
};
|
3615
|
+
if (fromAccount === 'margin' || toAccount === 'margin') {
|
3616
|
+
const symbol = this.safeString2 (params, 'symbol', 'currency_pair');
|
3617
|
+
if (symbol === undefined) {
|
3618
|
+
throw new ArgumentsRequired (this.id + ' transfer() requires params.symbol for isolated margin transfers');
|
3619
|
+
}
|
3620
|
+
const market = this.market (symbol);
|
3621
|
+
request['currency_pair'] = market['id'];
|
3622
|
+
params = this.omit (params, 'symbol');
|
3623
|
+
}
|
3624
|
+
if ((toId === 'futures') || (toId === 'delivery') || (fromId === 'futures') || (fromId === 'delivery')) {
|
3625
|
+
request['settle'] = currency['lowerCaseId'];
|
3626
|
+
}
|
3627
|
+
const response = await this.privateWalletPostTransfers (this.extend (request, params));
|
3628
|
+
//
|
3629
|
+
// according to the docs (however actual response seems to be an empty string '')
|
3630
|
+
//
|
3631
|
+
// {
|
3632
|
+
// "currency": "BTC",
|
3633
|
+
// "from": "spot",
|
3634
|
+
// "to": "margin",
|
3635
|
+
// "amount": "1",
|
3636
|
+
// "currency_pair": "BTC_USDT"
|
3637
|
+
// }
|
3638
|
+
//
|
3639
|
+
const transfer = this.parseTransfer (response, currency);
|
3640
|
+
return this.extend (transfer, {
|
3641
|
+
'fromAccount': fromAccount,
|
3642
|
+
'toAccount': toAccount,
|
3643
|
+
'amount': this.parseNumber (truncated),
|
3644
|
+
});
|
3645
|
+
}
|
3646
|
+
|
3647
|
+
parseTransfer (transfer, currency = undefined) {
|
3648
|
+
const timestamp = this.milliseconds ();
|
3649
|
+
return {
|
3650
|
+
'id': undefined,
|
3651
|
+
'timestamp': timestamp,
|
3652
|
+
'datetime': this.iso8601 (timestamp),
|
3653
|
+
'currency': this.safeCurrencyCode (undefined, currency),
|
3654
|
+
'amount': undefined,
|
3655
|
+
'fromAccount': undefined,
|
3656
|
+
'toAccount': undefined,
|
3657
|
+
'status': undefined,
|
3658
|
+
'info': transfer,
|
3659
|
+
};
|
3660
|
+
}
|
3661
|
+
|
3662
|
+
async setLeverage (leverage, symbol = undefined, params = {}) {
|
3663
|
+
if (symbol === undefined) {
|
3664
|
+
throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
|
3665
|
+
}
|
3666
|
+
// WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS
|
3667
|
+
// AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS
|
3668
|
+
if ((leverage < 0) || (leverage > 100)) {
|
3669
|
+
throw new BadRequest (this.id + ' setLeverage() leverage should be between 1 and 100');
|
3670
|
+
}
|
3671
|
+
await this.loadMarkets ();
|
3672
|
+
const market = this.market (symbol);
|
3673
|
+
const method = this.getSupportedMapping (market['type'], {
|
3674
|
+
'swap': 'privateFuturesPostSettlePositionsContractLeverage',
|
3675
|
+
'future': 'privateDeliveryPostSettlePositionsContractLeverage',
|
3676
|
+
});
|
3677
|
+
const request = this.prepareRequest (market);
|
3678
|
+
const defaultMarginType = this.safeString2 (this.options, 'marginType', 'defaultMarginType');
|
3679
|
+
const crossLeverageLimit = this.safeString (params, 'cross_leverage_limit');
|
3680
|
+
let marginType = this.safeString (params, 'marginType', defaultMarginType);
|
3681
|
+
if (crossLeverageLimit !== undefined) {
|
3682
|
+
marginType = 'cross';
|
3683
|
+
leverage = crossLeverageLimit;
|
3684
|
+
}
|
3685
|
+
if (marginType === 'cross') {
|
3686
|
+
request['query'] = {
|
3687
|
+
'cross_leverage_limit': leverage.toString (),
|
3688
|
+
'leverage': '0',
|
3689
|
+
};
|
3690
|
+
} else {
|
3691
|
+
request['query'] = {
|
3692
|
+
'leverage': leverage.toString (),
|
3693
|
+
};
|
3694
|
+
}
|
3695
|
+
const response = await this[method] (this.extend (request, params));
|
3696
|
+
//
|
3697
|
+
// {
|
3698
|
+
// "value": "0",
|
3699
|
+
// "leverage": "5",
|
3700
|
+
// "mode": "single",
|
3701
|
+
// "realised_point": "0",
|
3702
|
+
// "contract": "BTC_USDT",
|
3703
|
+
// "entry_price": "0",
|
3704
|
+
// "mark_price": "62035.86",
|
3705
|
+
// "history_point": "0",
|
3706
|
+
// "realised_pnl": "0",
|
3707
|
+
// "close_order": null,
|
3708
|
+
// "size": 0,
|
3709
|
+
// "cross_leverage_limit": "0",
|
3710
|
+
// "pending_orders": 0,
|
3711
|
+
// "adl_ranking": 6,
|
3712
|
+
// "maintenance_rate": "0.005",
|
3713
|
+
// "unrealised_pnl": "0",
|
3714
|
+
// "user": 2436035,
|
3715
|
+
// "leverage_max": "100",
|
3716
|
+
// "history_pnl": "0",
|
3717
|
+
// "risk_limit": "1000000",
|
3718
|
+
// "margin": "0",
|
3719
|
+
// "last_close_pnl": "0",
|
3720
|
+
// "liq_price": "0"
|
3721
|
+
// }
|
3722
|
+
//
|
3723
|
+
return response;
|
3724
|
+
}
|
3725
|
+
|
3726
|
+
parsePosition (position, market = undefined) {
|
3727
|
+
//
|
3728
|
+
// {
|
3729
|
+
// value: "12.475572",
|
3730
|
+
// leverage: "0",
|
3731
|
+
// mode: "single",
|
3732
|
+
// realised_point: "0",
|
3733
|
+
// contract: "BTC_USDT",
|
3734
|
+
// entry_price: "62422.6",
|
3735
|
+
// mark_price: "62377.86",
|
3736
|
+
// history_point: "0",
|
3737
|
+
// realised_pnl: "-0.00624226",
|
3738
|
+
// close_order: null,
|
3739
|
+
// size: "2",
|
3740
|
+
// cross_leverage_limit: "25",
|
3741
|
+
// pending_orders: "0",
|
3742
|
+
// adl_ranking: "5",
|
3743
|
+
// maintenance_rate: "0.005",
|
3744
|
+
// unrealised_pnl: "-0.008948",
|
3745
|
+
// user: "663337",
|
3746
|
+
// leverage_max: "100",
|
3747
|
+
// history_pnl: "14.98868396636",
|
3748
|
+
// risk_limit: "1000000",
|
3749
|
+
// margin: "0.740721495056",
|
3750
|
+
// last_close_pnl: "-0.041996015",
|
3751
|
+
// liq_price: "59058.58"
|
3752
|
+
// }
|
3753
|
+
//
|
3754
|
+
const contract = this.safeString (position, 'contract');
|
3755
|
+
market = this.safeMarket (contract, market);
|
3756
|
+
const size = this.safeString (position, 'size');
|
3757
|
+
let side = undefined;
|
3758
|
+
if (Precise.stringGt (size, '0')) {
|
3759
|
+
side = 'long';
|
3760
|
+
} else if (Precise.stringLt (size, '0')) {
|
3761
|
+
side = 'short';
|
3762
|
+
}
|
3763
|
+
const maintenanceRate = this.safeString (position, 'maintenance_rate');
|
3764
|
+
const notional = this.safeString (position, 'value');
|
3765
|
+
const leverage = this.safeString (position, 'leverage');
|
3766
|
+
let marginType = undefined;
|
3767
|
+
if (leverage === '0') {
|
3768
|
+
marginType = 'cross';
|
3769
|
+
} else {
|
3770
|
+
marginType = 'isolated';
|
3771
|
+
}
|
3772
|
+
const unrealisedPnl = this.safeString (position, 'unrealised_pnl');
|
3773
|
+
// Initial Position Margin = ( Position Value / Leverage ) + Close Position Fee
|
3774
|
+
// *The default leverage under the full position is the highest leverage in the market.
|
3775
|
+
// *Trading fee is charged as Taker Fee Rate (0.075%).
|
3776
|
+
const takerFee = '0.00075';
|
3777
|
+
const feePaid = Precise.stringMul (takerFee, notional);
|
3778
|
+
const initialMarginString = Precise.stringAdd (Precise.stringDiv (notional, leverage), feePaid);
|
3779
|
+
const percentage = Precise.stringMul (Precise.stringDiv (unrealisedPnl, initialMarginString), '100');
|
3780
|
+
return {
|
3781
|
+
'info': position,
|
3782
|
+
'symbol': this.safeString (market, 'symbol'),
|
3783
|
+
'timestamp': undefined,
|
3784
|
+
'datetime': undefined,
|
3785
|
+
'initialMargin': this.parseNumber (initialMarginString),
|
3786
|
+
'initialMarginPercentage': this.parseNumber (Precise.stringDiv (initialMarginString, notional)),
|
3787
|
+
'maintenanceMargin': this.parseNumber (Precise.stringMul (maintenanceRate, notional)),
|
3788
|
+
'maintenanceMarginPercentage': this.parseNumber (maintenanceRate),
|
3789
|
+
'entryPrice': this.safeNumber (position, 'entry_price'),
|
3790
|
+
'notional': this.parseNumber (notional),
|
3791
|
+
'leverage': this.safeNumber (position, 'leverage'),
|
3792
|
+
'unrealizedPnl': this.parseNumber (unrealisedPnl),
|
3793
|
+
'contracts': this.parseNumber (Precise.stringAbs (size)),
|
3794
|
+
'contractSize': this.safeValue (market, 'contractSize'),
|
3795
|
+
// realisedPnl: position['realised_pnl'],
|
3796
|
+
'marginRatio': undefined,
|
3797
|
+
'liquidationPrice': this.safeNumber (position, 'liq_price'),
|
3798
|
+
'markPrice': this.safeNumber (position, 'mark_price'),
|
3799
|
+
'collateral': this.safeNumber (position, 'margin'),
|
3800
|
+
'marginType': marginType,
|
3801
|
+
'side': side,
|
3802
|
+
'percentage': this.parseNumber (percentage),
|
3803
|
+
};
|
3804
|
+
}
|
3805
|
+
|
3806
|
+
parsePositions (positions) {
|
3807
|
+
const result = [];
|
3808
|
+
for (let i = 0; i < positions.length; i++) {
|
3809
|
+
result.push (this.parsePosition (positions[i]));
|
3810
|
+
}
|
3811
|
+
return result;
|
3812
|
+
}
|
3813
|
+
|
3814
|
+
async fetchPositions (symbols = undefined, params = {}) {
|
3815
|
+
/**
|
3816
|
+
* @method
|
3817
|
+
* @name gateio#fetchPositions
|
3818
|
+
* @description Fetch trades positions
|
3819
|
+
* @param {[str]} symbols Not used by Gateio, but parsed internally by CCXT
|
3820
|
+
* @param {dict} params exchange specific parameters
|
3821
|
+
* @param {str} params.settle 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
|
3822
|
+
* @param {str} params.type swap or future, if not provided this.options['defaultType'] is used
|
3823
|
+
* @returns An array of [position structures]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
3824
|
+
*/
|
3825
|
+
await this.loadMarkets ();
|
3826
|
+
const defaultType = this.safeString2 (this.options, 'fetchPositions', 'defaultType', 'swap');
|
3827
|
+
const type = this.safeString (params, 'type', defaultType);
|
3828
|
+
const method = this.getSupportedMapping (type, {
|
3829
|
+
'swap': 'privateFuturesGetSettlePositions',
|
3830
|
+
'future': 'privateDeliveryGetSettlePositions',
|
3831
|
+
});
|
3832
|
+
const defaultSettle = (type === 'swap') ? 'usdt' : 'btc';
|
3833
|
+
const settle = this.safeStringLower (params, 'settle', defaultSettle);
|
3834
|
+
const request = {
|
3835
|
+
'settle': settle,
|
3836
|
+
};
|
3837
|
+
const response = await this[method] (request);
|
3838
|
+
//
|
3839
|
+
// [
|
3840
|
+
// {
|
3841
|
+
// value: "12.475572",
|
3842
|
+
// leverage: "0",
|
3843
|
+
// mode: "single",
|
3844
|
+
// realised_point: "0",
|
3845
|
+
// contract: "BTC_USDT",
|
3846
|
+
// entry_price: "62422.6",
|
3847
|
+
// mark_price: "62377.86",
|
3848
|
+
// history_point: "0",
|
3849
|
+
// realised_pnl: "-0.00624226",
|
3850
|
+
// close_order: null,
|
3851
|
+
// size: "2",
|
3852
|
+
// cross_leverage_limit: "25",
|
3853
|
+
// pending_orders: "0",
|
3854
|
+
// adl_ranking: "5",
|
3855
|
+
// maintenance_rate: "0.005",
|
3856
|
+
// unrealised_pnl: "-0.008948",
|
3857
|
+
// user: "6693577",
|
3858
|
+
// leverage_max: "100",
|
3859
|
+
// history_pnl: "14.98868396636",
|
3860
|
+
// risk_limit: "1000000",
|
3861
|
+
// margin: "0.740721495056",
|
3862
|
+
// last_close_pnl: "-0.041996015",
|
3863
|
+
// liq_price: "59058.58"
|
3864
|
+
// }
|
3865
|
+
// ]
|
3866
|
+
//
|
3867
|
+
const result = this.parsePositions (response);
|
3868
|
+
return this.filterByArray (result, 'symbol', symbols, false);
|
3869
|
+
}
|
3870
|
+
|
3871
|
+
async fetchLeverageTiers (symbols = undefined, params = {}) {
|
3872
|
+
await this.loadMarkets ();
|
3873
|
+
const methodName = 'fetchLeverageTiers';
|
3874
|
+
const [ type, query ] = this.handleMarketTypeAndParams (methodName, undefined, params);
|
3875
|
+
const swap = type === 'swap';
|
3876
|
+
const defaultSettle = swap ? 'usdt' : 'btc';
|
3877
|
+
const settle = this.safeStringLower (query, 'settle', defaultSettle);
|
3878
|
+
query['settle'] = settle;
|
3879
|
+
if (type !== 'future' && type !== 'swap') {
|
3880
|
+
throw new BadRequest (this.id + ' ' + methodName + '() only supports swap and future');
|
3881
|
+
}
|
3882
|
+
const method = this.getSupportedMapping (type, {
|
3883
|
+
'swap': 'publicFuturesGetSettleContracts',
|
3884
|
+
'future': 'publicDeliveryGetSettleContracts',
|
3885
|
+
});
|
3886
|
+
const response = await this[method] (query);
|
3887
|
+
//
|
3888
|
+
// Perpetual swap
|
3889
|
+
//
|
3890
|
+
// [
|
3891
|
+
// {
|
3892
|
+
// "name": "BTC_USDT",
|
3893
|
+
// "type": "direct",
|
3894
|
+
// "quanto_multiplier": "0.0001",
|
3895
|
+
// "ref_discount_rate": "0",
|
3896
|
+
// "order_price_deviate": "0.5",
|
3897
|
+
// "maintenance_rate": "0.005",
|
3898
|
+
// "mark_type": "index",
|
3899
|
+
// "last_price": "38026",
|
3900
|
+
// "mark_price": "37985.6",
|
3901
|
+
// "index_price": "37954.92",
|
3902
|
+
// "funding_rate_indicative": "0.000219",
|
3903
|
+
// "mark_price_round": "0.01",
|
3904
|
+
// "funding_offset": 0,
|
3905
|
+
// "in_delisting": false,
|
3906
|
+
// "risk_limit_base": "1000000",
|
3907
|
+
// "interest_rate": "0.0003",
|
3908
|
+
// "order_price_round": "0.1",
|
3909
|
+
// "order_size_min": 1,
|
3910
|
+
// "ref_rebate_rate": "0.2",
|
3911
|
+
// "funding_interval": 28800,
|
3912
|
+
// "risk_limit_step": "1000000",
|
3913
|
+
// "leverage_min": "1",
|
3914
|
+
// "leverage_max": "100",
|
3915
|
+
// "risk_limit_max": "8000000",
|
3916
|
+
// "maker_fee_rate": "-0.00025",
|
3917
|
+
// "taker_fee_rate": "0.00075",
|
3918
|
+
// "funding_rate": "0.002053",
|
3919
|
+
// "order_size_max": 1000000,
|
3920
|
+
// "funding_next_apply": 1610035200,
|
3921
|
+
// "short_users": 977,
|
3922
|
+
// "config_change_time": 1609899548,
|
3923
|
+
// "trade_size": 28530850594,
|
3924
|
+
// "position_size": 5223816,
|
3925
|
+
// "long_users": 455,
|
3926
|
+
// "funding_impact_value": "60000",
|
3927
|
+
// "orders_limit": 50,
|
3928
|
+
// "trade_id": 10851092,
|
3929
|
+
// "orderbook_id": 2129638396
|
3930
|
+
// }
|
3931
|
+
// ]
|
3932
|
+
//
|
3933
|
+
// Delivery Futures
|
3934
|
+
//
|
3935
|
+
// [
|
3936
|
+
// {
|
3937
|
+
// "name": "BTC_USDT_20200814",
|
3938
|
+
// "underlying": "BTC_USDT",
|
3939
|
+
// "cycle": "WEEKLY",
|
3940
|
+
// "type": "direct",
|
3941
|
+
// "quanto_multiplier": "0.0001",
|
3942
|
+
// "mark_type": "index",
|
3943
|
+
// "last_price": "9017",
|
3944
|
+
// "mark_price": "9019",
|
3945
|
+
// "index_price": "9005.3",
|
3946
|
+
// "basis_rate": "0.185095",
|
3947
|
+
// "basis_value": "13.7",
|
3948
|
+
// "basis_impact_value": "100000",
|
3949
|
+
// "settle_price": "0",
|
3950
|
+
// "settle_price_interval": 60,
|
3951
|
+
// "settle_price_duration": 1800,
|
3952
|
+
// "settle_fee_rate": "0.0015",
|
3953
|
+
// "expire_time": 1593763200,
|
3954
|
+
// "order_price_round": "0.1",
|
3955
|
+
// "mark_price_round": "0.1",
|
3956
|
+
// "leverage_min": "1",
|
3957
|
+
// "leverage_max": "100",
|
3958
|
+
// "maintenance_rate": "1000000",
|
3959
|
+
// "risk_limit_base": "140.726652109199",
|
3960
|
+
// "risk_limit_step": "1000000",
|
3961
|
+
// "risk_limit_max": "8000000",
|
3962
|
+
// "maker_fee_rate": "-0.00025",
|
3963
|
+
// "taker_fee_rate": "0.00075",
|
3964
|
+
// "ref_discount_rate": "0",
|
3965
|
+
// "ref_rebate_rate": "0.2",
|
3966
|
+
// "order_price_deviate": "0.5",
|
3967
|
+
// "order_size_min": 1,
|
3968
|
+
// "order_size_max": 1000000,
|
3969
|
+
// "orders_limit": 50,
|
3970
|
+
// "orderbook_id": 63,
|
3971
|
+
// "trade_id": 26,
|
3972
|
+
// "trade_size": 435,
|
3973
|
+
// "position_size": 130,
|
3974
|
+
// "config_change_time": 1593158867,
|
3975
|
+
// "in_delisting": false
|
3976
|
+
// }
|
3977
|
+
// ]
|
3978
|
+
//
|
3979
|
+
return this.parseLeverageTiers (response, symbols, 'name');
|
3980
|
+
}
|
3981
|
+
|
3982
|
+
parseMarketLeverageTiers (info, market = undefined) {
|
3983
|
+
/**
|
3984
|
+
* @ignore
|
3985
|
+
* @method
|
3986
|
+
* @description https://www.gate.io/help/futures/perpetual/22162/instrctions-of-risk-limit
|
3987
|
+
* @param {dict} info Exchange market response for 1 market
|
3988
|
+
* @param {dict} market CCXT market
|
3989
|
+
*/
|
3990
|
+
//
|
3991
|
+
// Perpetual swap
|
3992
|
+
//
|
3993
|
+
// {
|
3994
|
+
// "name": "BTC_USDT",
|
3995
|
+
// "type": "direct",
|
3996
|
+
// "quanto_multiplier": "0.0001",
|
3997
|
+
// "ref_discount_rate": "0",
|
3998
|
+
// "order_price_deviate": "0.5",
|
3999
|
+
// "maintenance_rate": "0.005",
|
4000
|
+
// "mark_type": "index",
|
4001
|
+
// "last_price": "38026",
|
4002
|
+
// "mark_price": "37985.6",
|
4003
|
+
// "index_price": "37954.92",
|
4004
|
+
// "funding_rate_indicative": "0.000219",
|
4005
|
+
// "mark_price_round": "0.01",
|
4006
|
+
// "funding_offset": 0,
|
4007
|
+
// "in_delisting": false,
|
4008
|
+
// "risk_limit_base": "1000000",
|
4009
|
+
// "interest_rate": "0.0003",
|
4010
|
+
// "order_price_round": "0.1",
|
4011
|
+
// "order_size_min": 1,
|
4012
|
+
// "ref_rebate_rate": "0.2",
|
4013
|
+
// "funding_interval": 28800,
|
4014
|
+
// "risk_limit_step": "1000000",
|
4015
|
+
// "leverage_min": "1",
|
4016
|
+
// "leverage_max": "100",
|
4017
|
+
// "risk_limit_max": "8000000",
|
4018
|
+
// "maker_fee_rate": "-0.00025",
|
4019
|
+
// "taker_fee_rate": "0.00075",
|
4020
|
+
// "funding_rate": "0.002053",
|
4021
|
+
// "order_size_max": 1000000,
|
4022
|
+
// "funding_next_apply": 1610035200,
|
4023
|
+
// "short_users": 977,
|
4024
|
+
// "config_change_time": 1609899548,
|
4025
|
+
// "trade_size": 28530850594,
|
4026
|
+
// "position_size": 5223816,
|
4027
|
+
// "long_users": 455,
|
4028
|
+
// "funding_impact_value": "60000",
|
4029
|
+
// "orders_limit": 50,
|
4030
|
+
// "trade_id": 10851092,
|
4031
|
+
// "orderbook_id": 2129638396
|
4032
|
+
// }
|
4033
|
+
//
|
4034
|
+
// Delivery Futures
|
4035
|
+
//
|
4036
|
+
// {
|
4037
|
+
// "name": "BTC_USDT_20200814",
|
4038
|
+
// "underlying": "BTC_USDT",
|
4039
|
+
// "cycle": "WEEKLY",
|
4040
|
+
// "type": "direct",
|
4041
|
+
// "quanto_multiplier": "0.0001",
|
4042
|
+
// "mark_type": "index",
|
4043
|
+
// "last_price": "9017",
|
4044
|
+
// "mark_price": "9019",
|
4045
|
+
// "index_price": "9005.3",
|
4046
|
+
// "basis_rate": "0.185095",
|
4047
|
+
// "basis_value": "13.7",
|
4048
|
+
// "basis_impact_value": "100000",
|
4049
|
+
// "settle_price": "0",
|
4050
|
+
// "settle_price_interval": 60,
|
4051
|
+
// "settle_price_duration": 1800,
|
4052
|
+
// "settle_fee_rate": "0.0015",
|
4053
|
+
// "expire_time": 1593763200,
|
4054
|
+
// "order_price_round": "0.1",
|
4055
|
+
// "mark_price_round": "0.1",
|
4056
|
+
// "leverage_min": "1",
|
4057
|
+
// "leverage_max": "100",
|
4058
|
+
// "maintenance_rate": "1000000",
|
4059
|
+
// "risk_limit_base": "140.726652109199",
|
4060
|
+
// "risk_limit_step": "1000000",
|
4061
|
+
// "risk_limit_max": "8000000",
|
4062
|
+
// "maker_fee_rate": "-0.00025",
|
4063
|
+
// "taker_fee_rate": "0.00075",
|
4064
|
+
// "ref_discount_rate": "0",
|
4065
|
+
// "ref_rebate_rate": "0.2",
|
4066
|
+
// "order_price_deviate": "0.5",
|
4067
|
+
// "order_size_min": 1,
|
4068
|
+
// "order_size_max": 1000000,
|
4069
|
+
// "orders_limit": 50,
|
4070
|
+
// "orderbook_id": 63,
|
4071
|
+
// "trade_id": 26,
|
4072
|
+
// "trade_size": 435,
|
4073
|
+
// "position_size": 130,
|
4074
|
+
// "config_change_time": 1593158867,
|
4075
|
+
// "in_delisting": false
|
4076
|
+
// }
|
4077
|
+
//
|
4078
|
+
const maintenanceMarginUnit = this.safeString (info, 'maintenance_rate'); // '0.005',
|
4079
|
+
const leverageMax = this.safeString (info, 'leverage_max'); // '100',
|
4080
|
+
const riskLimitStep = this.safeString (info, 'risk_limit_step'); // '1000000',
|
4081
|
+
const riskLimitMax = this.safeString (info, 'risk_limit_max'); // '16000000',
|
4082
|
+
const initialMarginUnit = Precise.stringDiv ('1', leverageMax);
|
4083
|
+
let maintenanceMarginRate = maintenanceMarginUnit;
|
4084
|
+
let initialMarginRatio = initialMarginUnit;
|
4085
|
+
let floor = '0';
|
4086
|
+
const tiers = [];
|
4087
|
+
while (Precise.stringLt (floor, riskLimitMax)) {
|
4088
|
+
const cap = Precise.stringAdd (floor, riskLimitStep);
|
4089
|
+
tiers.push ({
|
4090
|
+
'tier': this.parseNumber (Precise.stringDiv (cap, riskLimitStep)),
|
4091
|
+
'currency': this.safeString (market, 'settle'),
|
4092
|
+
'minNotional': this.parseNumber (floor),
|
4093
|
+
'maxNotional': this.parseNumber (cap),
|
4094
|
+
'maintenanceMarginRate': this.parseNumber (maintenanceMarginRate),
|
4095
|
+
'maxLeverage': this.parseNumber (Precise.stringDiv ('1', initialMarginRatio)),
|
4096
|
+
'info': info,
|
4097
|
+
});
|
4098
|
+
maintenanceMarginRate = Precise.stringAdd (maintenanceMarginRate, maintenanceMarginUnit);
|
4099
|
+
initialMarginRatio = Precise.stringAdd (initialMarginRatio, initialMarginUnit);
|
4100
|
+
floor = cap;
|
4101
|
+
}
|
4102
|
+
return tiers;
|
4103
|
+
}
|
4104
|
+
|
4105
|
+
sign (path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
|
4106
|
+
const authentication = api[0]; // public, private
|
4107
|
+
const type = api[1]; // spot, margin, future, delivery
|
4108
|
+
let query = this.omit (params, this.extractParams (path));
|
4109
|
+
path = this.implodeParams (path, params);
|
4110
|
+
const endPart = (path === '') ? '' : ('/' + path);
|
4111
|
+
const entirePath = '/' + type + endPart;
|
4112
|
+
let url = this.urls['api'][authentication][type];
|
4113
|
+
if (url === undefined) {
|
4114
|
+
throw new NotSupported (this.id + ' does not have a testnet for the ' + type + ' market type.');
|
4115
|
+
}
|
4116
|
+
url += entirePath;
|
4117
|
+
if (authentication === 'public') {
|
4118
|
+
if (Object.keys (query).length) {
|
4119
|
+
url += '?' + this.urlencode (query);
|
4120
|
+
}
|
4121
|
+
} else {
|
4122
|
+
let queryString = '';
|
4123
|
+
if ((method === 'GET') || (method === 'DELETE')) {
|
4124
|
+
if (Object.keys (query).length) {
|
4125
|
+
queryString = this.urlencode (query);
|
4126
|
+
url += '?' + queryString;
|
4127
|
+
}
|
4128
|
+
} else {
|
4129
|
+
const urlQueryParams = this.safeValue (query, 'query', {});
|
4130
|
+
if (Object.keys (urlQueryParams).length) {
|
4131
|
+
queryString = this.urlencode (urlQueryParams);
|
4132
|
+
url += '?' + queryString;
|
4133
|
+
}
|
4134
|
+
query = this.omit (query, 'query');
|
4135
|
+
body = this.json (query);
|
4136
|
+
}
|
4137
|
+
const bodyPayload = (body === undefined) ? '' : body;
|
4138
|
+
const bodySignature = this.hash (this.encode (bodyPayload), 'sha512');
|
4139
|
+
const timestamp = this.seconds ();
|
4140
|
+
const timestampString = timestamp.toString ();
|
4141
|
+
const signaturePath = '/api/' + this.version + entirePath;
|
4142
|
+
const payloadArray = [ method.toUpperCase (), signaturePath, queryString, bodySignature, timestampString ];
|
4143
|
+
// eslint-disable-next-line quotes
|
4144
|
+
const payload = payloadArray.join ("\n");
|
4145
|
+
const signature = this.hmac (this.encode (payload), this.encode (this.secret), 'sha512');
|
4146
|
+
headers = {
|
4147
|
+
'KEY': this.apiKey,
|
4148
|
+
'Timestamp': timestampString,
|
4149
|
+
'SIGN': signature,
|
4150
|
+
'Content-Type': 'application/json',
|
4151
|
+
};
|
4152
|
+
}
|
4153
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
4154
|
+
}
|
4155
|
+
|
4156
|
+
handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
4157
|
+
if (response === undefined) {
|
4158
|
+
return;
|
4159
|
+
}
|
4160
|
+
//
|
4161
|
+
// {"label": "ORDER_NOT_FOUND", "message": "Order not found"}
|
4162
|
+
// {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: status"}
|
4163
|
+
// {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: Trigger.rule"}
|
4164
|
+
// {"label": "INVALID_PARAM_VALUE", "message": "invalid argument: trigger.expiration invalid range"}
|
4165
|
+
// {"label": "INVALID_ARGUMENT", "detail": "invalid size"}
|
4166
|
+
//
|
4167
|
+
const label = this.safeString (response, 'label');
|
4168
|
+
if (label !== undefined) {
|
4169
|
+
const feedback = this.id + ' ' + body;
|
4170
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], label, feedback);
|
4171
|
+
throw new ExchangeError (feedback);
|
4172
|
+
}
|
4173
|
+
}
|
4174
|
+
};
|