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/bybit.js
ADDED
@@ -0,0 +1,3372 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const { TICK_SIZE } = require ('./base/functions/number');
|
7
|
+
const { AuthenticationError, ExchangeError, ArgumentsRequired, PermissionDenied, InvalidOrder, OrderNotFound, InsufficientFunds, BadRequest, RateLimitExceeded, InvalidNonce } = require ('./base/errors');
|
8
|
+
const Precise = require ('./base/Precise');
|
9
|
+
|
10
|
+
// ---------------------------------------------------------------------------
|
11
|
+
|
12
|
+
module.exports = class bybit extends Exchange {
|
13
|
+
describe () {
|
14
|
+
return this.deepExtend (super.describe (), {
|
15
|
+
'id': 'bybit',
|
16
|
+
'name': 'Bybit',
|
17
|
+
'countries': [ 'VG' ], // British Virgin Islands
|
18
|
+
'version': 'v2',
|
19
|
+
'userAgent': undefined,
|
20
|
+
// 50 requests per second for GET requests, 1000ms / 50 = 20ms between requests
|
21
|
+
// 20 requests per second for POST requests, cost = 50 / 20 = 2.5
|
22
|
+
'rateLimit': 20,
|
23
|
+
'hostname': 'bybit.com', // bybit.com, bytick.com
|
24
|
+
'has': {
|
25
|
+
'CORS': true,
|
26
|
+
'spot': true,
|
27
|
+
'margin': false,
|
28
|
+
'swap': true,
|
29
|
+
'future': true,
|
30
|
+
'option': undefined,
|
31
|
+
'cancelAllOrders': true,
|
32
|
+
'cancelOrder': true,
|
33
|
+
'createOrder': true,
|
34
|
+
'createStopLimitOrder': true,
|
35
|
+
'createStopMarketOrder': true,
|
36
|
+
'createStopOrder': true,
|
37
|
+
'editOrder': true,
|
38
|
+
'fetchBalance': true,
|
39
|
+
'fetchBorrowRate': false,
|
40
|
+
'fetchBorrowRates': false,
|
41
|
+
'fetchClosedOrders': true,
|
42
|
+
'fetchDeposits': true,
|
43
|
+
'fetchFundingRate': true,
|
44
|
+
'fetchFundingRateHistory': false,
|
45
|
+
'fetchIndexOHLCV': true,
|
46
|
+
'fetchLedger': true,
|
47
|
+
'fetchMarketLeverageTiers': true,
|
48
|
+
'fetchMarkets': true,
|
49
|
+
'fetchMarkOHLCV': true,
|
50
|
+
'fetchMyTrades': true,
|
51
|
+
'fetchOHLCV': true,
|
52
|
+
'fetchOpenOrders': true,
|
53
|
+
'fetchOrder': true,
|
54
|
+
'fetchOrderBook': true,
|
55
|
+
'fetchOrders': true,
|
56
|
+
'fetchOrderTrades': true,
|
57
|
+
'fetchPositions': true,
|
58
|
+
'fetchPremiumIndexOHLCV': true,
|
59
|
+
'fetchTicker': true,
|
60
|
+
'fetchTickers': true,
|
61
|
+
'fetchTime': true,
|
62
|
+
'fetchTrades': true,
|
63
|
+
'fetchTradingFee': false,
|
64
|
+
'fetchTradingFees': false,
|
65
|
+
'fetchTransactions': undefined,
|
66
|
+
'fetchWithdrawals': true,
|
67
|
+
'setLeverage': true,
|
68
|
+
'setMarginMode': true,
|
69
|
+
},
|
70
|
+
'timeframes': {
|
71
|
+
'1m': '1',
|
72
|
+
'3m': '3',
|
73
|
+
'5m': '5',
|
74
|
+
'15m': '15',
|
75
|
+
'30m': '30',
|
76
|
+
'1h': '60',
|
77
|
+
'2h': '120',
|
78
|
+
'4h': '240',
|
79
|
+
'6h': '360',
|
80
|
+
'12h': '720',
|
81
|
+
'1d': 'D',
|
82
|
+
'1w': 'W',
|
83
|
+
'1M': 'M',
|
84
|
+
'1y': 'Y',
|
85
|
+
},
|
86
|
+
'urls': {
|
87
|
+
'test': {
|
88
|
+
'spot': 'https://api-testnet.{hostname}',
|
89
|
+
'futures': 'https://api-testnet.{hostname}',
|
90
|
+
'v2': 'https://api-testnet.{hostname}',
|
91
|
+
'public': 'https://api-testnet.{hostname}',
|
92
|
+
'private': 'https://api-testnet.{hostname}',
|
93
|
+
},
|
94
|
+
'logo': 'https://user-images.githubusercontent.com/51840849/76547799-daff5b80-649e-11ea-87fb-3be9bac08954.jpg',
|
95
|
+
'api': {
|
96
|
+
'spot': 'https://api.{hostname}',
|
97
|
+
'futures': 'https://api.{hostname}',
|
98
|
+
'v2': 'https://api.{hostname}',
|
99
|
+
'public': 'https://api.{hostname}',
|
100
|
+
'private': 'https://api.{hostname}',
|
101
|
+
},
|
102
|
+
'www': 'https://www.bybit.com',
|
103
|
+
'doc': [
|
104
|
+
'https://bybit-exchange.github.io/docs/inverse/',
|
105
|
+
'https://bybit-exchange.github.io/docs/linear/',
|
106
|
+
'https://github.com/bybit-exchange',
|
107
|
+
],
|
108
|
+
'fees': 'https://help.bybit.com/hc/en-us/articles/360039261154',
|
109
|
+
'referral': 'https://www.bybit.com/app/register?ref=X7Prm',
|
110
|
+
},
|
111
|
+
'api': {
|
112
|
+
// outdated endpoints -----------------------------------------
|
113
|
+
'spot': {
|
114
|
+
'public': {
|
115
|
+
'get': [
|
116
|
+
'symbols',
|
117
|
+
],
|
118
|
+
},
|
119
|
+
'quote': {
|
120
|
+
'get': [
|
121
|
+
'depth',
|
122
|
+
'depth/merged',
|
123
|
+
'trades',
|
124
|
+
'kline',
|
125
|
+
'ticker/24hr',
|
126
|
+
'ticker/price',
|
127
|
+
'ticker/book_ticker',
|
128
|
+
],
|
129
|
+
},
|
130
|
+
'private': {
|
131
|
+
'get': [
|
132
|
+
'order',
|
133
|
+
'open-orders',
|
134
|
+
'history-orders',
|
135
|
+
'myTrades',
|
136
|
+
'account',
|
137
|
+
'time',
|
138
|
+
],
|
139
|
+
'post': [
|
140
|
+
'order',
|
141
|
+
],
|
142
|
+
'delete': [
|
143
|
+
'order',
|
144
|
+
'order/fast',
|
145
|
+
],
|
146
|
+
},
|
147
|
+
'order': {
|
148
|
+
'delete': [
|
149
|
+
'batch-cancel',
|
150
|
+
'batch-fast-cancel',
|
151
|
+
'batch-cancel-by-ids',
|
152
|
+
],
|
153
|
+
},
|
154
|
+
},
|
155
|
+
'futures': {
|
156
|
+
'private': {
|
157
|
+
'get': [
|
158
|
+
'order/list',
|
159
|
+
'order',
|
160
|
+
'stop-order/list',
|
161
|
+
'stop-order',
|
162
|
+
'position/list',
|
163
|
+
'execution/list',
|
164
|
+
'trade/closed-pnl/list',
|
165
|
+
],
|
166
|
+
'post': [
|
167
|
+
'order/create',
|
168
|
+
'order/cancel',
|
169
|
+
'order/cancelAll',
|
170
|
+
'order/replace',
|
171
|
+
'stop-order/create',
|
172
|
+
'stop-order/cancel',
|
173
|
+
'stop-order/cancelAll',
|
174
|
+
'stop-order/replace',
|
175
|
+
'position/change-position-margin',
|
176
|
+
'position/trading-stop',
|
177
|
+
'position/leverage/save',
|
178
|
+
'position/switch-mode',
|
179
|
+
'position/switch-isolated',
|
180
|
+
'position/risk-limit',
|
181
|
+
],
|
182
|
+
},
|
183
|
+
},
|
184
|
+
'v2': {
|
185
|
+
'public': {
|
186
|
+
'get': [
|
187
|
+
'orderBook/L2',
|
188
|
+
'kline/list',
|
189
|
+
'tickers',
|
190
|
+
'trading-records',
|
191
|
+
'symbols',
|
192
|
+
'liq-records',
|
193
|
+
'mark-price-kline',
|
194
|
+
'index-price-kline',
|
195
|
+
'premium-index-kline',
|
196
|
+
'open-interest',
|
197
|
+
'big-deal',
|
198
|
+
'account-ratio',
|
199
|
+
'time',
|
200
|
+
'announcement',
|
201
|
+
'funding/prev-funding-rate',
|
202
|
+
'risk-limit/list',
|
203
|
+
],
|
204
|
+
},
|
205
|
+
'private': {
|
206
|
+
'get': [
|
207
|
+
'order/list',
|
208
|
+
'order',
|
209
|
+
'stop-order/list',
|
210
|
+
'stop-order',
|
211
|
+
'position/list',
|
212
|
+
'position/fee-rate',
|
213
|
+
'execution/list',
|
214
|
+
'trade/closed-pnl/list',
|
215
|
+
'funding/prev-funding-rate',
|
216
|
+
'funding/prev-funding',
|
217
|
+
'funding/predicted-funding',
|
218
|
+
'account/api-key',
|
219
|
+
'account/lcp',
|
220
|
+
'wallet/balance',
|
221
|
+
'wallet/fund/records',
|
222
|
+
'wallet/withdraw/list',
|
223
|
+
'exchange-order/list',
|
224
|
+
],
|
225
|
+
'post': [
|
226
|
+
'order/create',
|
227
|
+
'order/cancel',
|
228
|
+
'order/cancelAll',
|
229
|
+
'order/replace',
|
230
|
+
'stop-order/create',
|
231
|
+
'stop-order/cancel',
|
232
|
+
'stop-order/cancelAll',
|
233
|
+
'stop-order/replace',
|
234
|
+
'position/change-position-margin',
|
235
|
+
'position/trading-stop',
|
236
|
+
'position/leverage/save',
|
237
|
+
'position/switch-mode',
|
238
|
+
'position/switch-isolated',
|
239
|
+
'position/risk-limit',
|
240
|
+
],
|
241
|
+
},
|
242
|
+
},
|
243
|
+
// new endpoints ------------------------------------------
|
244
|
+
'public': {
|
245
|
+
'get': {
|
246
|
+
// inverse swap
|
247
|
+
'v2/public/orderBook/L2': 1,
|
248
|
+
'v2/public/kline/list': 3,
|
249
|
+
'v2/public/tickers': 1,
|
250
|
+
'v2/public/trading-records': 1,
|
251
|
+
'v2/public/symbols': 1,
|
252
|
+
'v2/public/mark-price-kline': 3,
|
253
|
+
'v2/public/index-price-kline': 3,
|
254
|
+
'v2/public/premium-index-kline': 2,
|
255
|
+
'v2/public/open-interest': 1,
|
256
|
+
'v2/public/big-deal': 1,
|
257
|
+
'v2/public/account-ratio': 1,
|
258
|
+
'v2/public/funding-rate': 1,
|
259
|
+
'v2/public/elite-ratio': 1,
|
260
|
+
// linear swap USDT
|
261
|
+
'public/linear/kline': 3,
|
262
|
+
'public/linear/recent-trading-records': 1,
|
263
|
+
'public/linear/funding/prev-funding-rate': 1,
|
264
|
+
'public/linear/mark-price-kline': 1,
|
265
|
+
'public/linear/index-price-kline': 1,
|
266
|
+
'public/linear/premium-index-kline': 1,
|
267
|
+
// spot
|
268
|
+
'spot/v1/time': 1,
|
269
|
+
'spot/v1/symbols': 1,
|
270
|
+
'spot/quote/v1/depth': 1,
|
271
|
+
'spot/quote/v1/depth/merged': 1,
|
272
|
+
'spot/quote/v1/trades': 1,
|
273
|
+
'spot/quote/v1/kline': 1,
|
274
|
+
'spot/quote/v1/ticker/24hr': 1,
|
275
|
+
'spot/quote/v1/ticker/price': 1,
|
276
|
+
'spot/quote/v1/ticker/book_ticker': 1,
|
277
|
+
// data
|
278
|
+
'v2/public/time': 1,
|
279
|
+
'v2/public/announcement': 1,
|
280
|
+
// USDC endpoints are testnet only as of 2022 Jan 11 ----------
|
281
|
+
// option USDC (testnet only)
|
282
|
+
'option/usdc/openapi/public/v1/order-book': 1,
|
283
|
+
'option/usdc/openapi/public/v1/symbols': 1,
|
284
|
+
'option/usdc/openapi/public/v1/tick': 1,
|
285
|
+
'option/usdc/openapi/public/v1/delivery-price': 1,
|
286
|
+
'option/usdc/openapi/public/v1/query-trade-latest': 1,
|
287
|
+
// perpetual swap USDC (testnet only)
|
288
|
+
'perpetual/usdc/openapi/public/v1/order-book': 1,
|
289
|
+
'perpetual/usdc/openapi/public/v1/symbols': 1,
|
290
|
+
'perpetual/usdc/openapi/public/v1/tick': 1,
|
291
|
+
'perpetual/usdc/openapi/public/v1/kline/list': 1,
|
292
|
+
'perpetual/usdc/openapi/public/v1/mark-price-kline': 1,
|
293
|
+
'perpetual/usdc/openapi/public/v1/index-price-kline': 1,
|
294
|
+
'perpetual/usdc/openapi/public/v1/premium-index-kline': 1,
|
295
|
+
'perpetual/usdc/openapi/public/v1/open-interest': 1,
|
296
|
+
'perpetual/usdc/openapi/public/v1/big-deal': 1,
|
297
|
+
'perpetual/usdc/openapi/public/v1/account-ratio': 1,
|
298
|
+
},
|
299
|
+
// outdated endpoints--------------------------------------
|
300
|
+
'linear': {
|
301
|
+
'get': [
|
302
|
+
'kline',
|
303
|
+
'recent-trading-records',
|
304
|
+
'funding/prev-funding-rate',
|
305
|
+
'mark-price-kline',
|
306
|
+
'index-price-kline',
|
307
|
+
'premium-index-kline',
|
308
|
+
'risk-limit',
|
309
|
+
],
|
310
|
+
},
|
311
|
+
},
|
312
|
+
// new endpoints ------------------------------------------
|
313
|
+
'private': {
|
314
|
+
'get': {
|
315
|
+
// inverse swap
|
316
|
+
'v2/private/order/list': 5,
|
317
|
+
'v2/private/order': 5,
|
318
|
+
'v2/private/stop-order/list': 5,
|
319
|
+
'v2/private/stop-order': 1,
|
320
|
+
'v2/private/position/list': 25,
|
321
|
+
'v2/private/position/fee-rate': 40,
|
322
|
+
'v2/private/execution/list': 25,
|
323
|
+
'v2/private/trade/closed-pnl/list': 1,
|
324
|
+
'v2/public/risk-limit/list': 1, // TODO check
|
325
|
+
'v2/public/funding/prev-funding-rate': 25, // TODO check
|
326
|
+
'v2/private/funding/prev-funding': 25,
|
327
|
+
'v2/private/funding/predicted-funding': 25,
|
328
|
+
'v2/private/account/api-key': 5,
|
329
|
+
'v2/private/account/lcp': 1,
|
330
|
+
'v2/private/wallet/balance': 25, // 120 per minute = 2 per second => cost = 50 / 2 = 25
|
331
|
+
'v2/private/wallet/fund/records': 25,
|
332
|
+
'v2/private/wallet/withdraw/list': 25,
|
333
|
+
'v2/private/exchange-order/list': 1,
|
334
|
+
// linear swap USDT
|
335
|
+
'private/linear/order/list': 5, // 600 per minute = 10 per second => cost = 50 / 10 = 5
|
336
|
+
'private/linear/order/search': 5,
|
337
|
+
'private/linear/stop-order/list': 5,
|
338
|
+
'private/linear/stop-order/search': 5,
|
339
|
+
'private/linear/position/list': 25,
|
340
|
+
'private/linear/trade/execution/list': 25,
|
341
|
+
'private/linear/trade/closed-pnl/list': 25,
|
342
|
+
'public/linear/risk-limit': 1,
|
343
|
+
'private/linear/funding/predicted-funding': 25,
|
344
|
+
'private/linear/funding/prev-funding': 25,
|
345
|
+
// inverse futures
|
346
|
+
'futures/private/order/list': 5,
|
347
|
+
'futures/private/order': 5,
|
348
|
+
'futures/private/stop-order/list': 5,
|
349
|
+
'futures/private/stop-order': 5,
|
350
|
+
'futures/private/position/list': 25,
|
351
|
+
'futures/private/execution/list': 25,
|
352
|
+
'futures/private/trade/closed-pnl/list': 1,
|
353
|
+
// spot
|
354
|
+
'spot/v1/account': 2.5,
|
355
|
+
'spot/v1/order': 2.5,
|
356
|
+
'spot/v1/open-orders': 2.5,
|
357
|
+
'spot/v1/history-orders': 2.5,
|
358
|
+
'spot/v1/myTrades': 2.5,
|
359
|
+
// account
|
360
|
+
'asset/v1/private/transfer/list': 50, // 60 per minute = 1 per second => cost = 50 / 1 = 50
|
361
|
+
'asset/v1/private/sub-member/transfer/list': 50,
|
362
|
+
'asset/v1/private/sub-member/member-ids': 50,
|
363
|
+
},
|
364
|
+
'post': {
|
365
|
+
// inverse swap
|
366
|
+
'v2/private/order/create': 30,
|
367
|
+
'v2/private/order/cancel': 30,
|
368
|
+
'v2/private/order/cancelAll': 300, // 100 per minute + 'consumes 10 requests'
|
369
|
+
'v2/private/order/replace': 30,
|
370
|
+
'v2/private/stop-order/create': 30,
|
371
|
+
'v2/private/stop-order/cancel': 30,
|
372
|
+
'v2/private/stop-order/cancelAll': 300,
|
373
|
+
'v2/private/stop-order/replace': 30,
|
374
|
+
'v2/private/position/change-position-margin': 40,
|
375
|
+
'v2/private/position/trading-stop': 40,
|
376
|
+
'v2/private/position/leverage/save': 40,
|
377
|
+
'v2/private/tpsl/switch-mode': 40,
|
378
|
+
'v2/private/position/switch-isolated': 2.5,
|
379
|
+
'v2/private/position/risk-limit': 2.5,
|
380
|
+
'v2/private/position/switch-mode': 2.5,
|
381
|
+
// linear swap USDT
|
382
|
+
'private/linear/order/create': 30, // 100 per minute = 1.666 per second => cost = 50 / 1.6666 = 30
|
383
|
+
'private/linear/order/cancel': 30,
|
384
|
+
'private/linear/order/cancel-all': 300, // 100 per minute + 'consumes 10 requests'
|
385
|
+
'private/linear/order/replace': 30,
|
386
|
+
'private/linear/stop-order/create': 30,
|
387
|
+
'private/linear/stop-order/cancel': 30,
|
388
|
+
'private/linear/stop-order/cancel-all': 300,
|
389
|
+
'private/linear/stop-order/replace': 30,
|
390
|
+
'private/linear/position/set-auto-add-margin': 40,
|
391
|
+
'private/linear/position/switch-isolated': 40,
|
392
|
+
'private/linear/position/switch-mode': 40,
|
393
|
+
'private/linear/tpsl/switch-mode': 2.5,
|
394
|
+
'private/linear/position/add-margin': 40,
|
395
|
+
'private/linear/position/set-leverage': 40, // 75 per minute = 1.25 per second => cost = 50 / 1.25 = 40
|
396
|
+
'private/linear/position/trading-stop': 40,
|
397
|
+
'private/linear/position/set-risk': 2.5,
|
398
|
+
// inverse futures
|
399
|
+
'futures/private/order/create': 30,
|
400
|
+
'futures/private/order/cancel': 30,
|
401
|
+
'futures/private/order/cancelAll': 30,
|
402
|
+
'futures/private/order/replace': 30,
|
403
|
+
'futures/private/stop-order/create': 30,
|
404
|
+
'futures/private/stop-order/cancel': 30,
|
405
|
+
'futures/private/stop-order/cancelAll': 30,
|
406
|
+
'futures/private/stop-order/replace': 30,
|
407
|
+
'futures/private/position/change-position-margin': 40,
|
408
|
+
'futures/private/position/trading-stop': 40,
|
409
|
+
'futures/private/position/leverage/save': 40,
|
410
|
+
'futures/private/position/switch-mode': 40,
|
411
|
+
'futures/private/tpsl/switch-mode': 40,
|
412
|
+
'futures/private/position/switch-isolated': 40,
|
413
|
+
'futures/private/position/risk-limit': 2.5,
|
414
|
+
// spot
|
415
|
+
'spot/v1/order': 2.5,
|
416
|
+
// account
|
417
|
+
'asset/v1/private/transfer': 150, // 20 per minute = 0.333 per second => cost = 50 / 0.3333 = 150
|
418
|
+
'asset/v1/private/sub-member/transfer': 150,
|
419
|
+
// USDC endpoints are testnet only as of 2022 Jan 11 ----------
|
420
|
+
// option USDC (testnet only)
|
421
|
+
'option/usdc/openapi/private/v1/place-order': 2.5,
|
422
|
+
'option/usdc/openapi/private/v1/batch-place-order': 2.5,
|
423
|
+
'option/usdc/openapi/private/v1/replace-order': 2.5,
|
424
|
+
'option/usdc/openapi/private/v1/batch-replace-orders': 2.5,
|
425
|
+
'option/usdc/openapi/private/v1/cancel-order': 2.5,
|
426
|
+
'option/usdc/openapi/private/v1/batch-cancel-orders': 2.5,
|
427
|
+
'option/usdc/openapi/private/v1/cancel-all': 2.5,
|
428
|
+
'option/usdc/openapi/private/v1/query-active-orders': 2.5,
|
429
|
+
'option/usdc/openapi/private/v1/query-order-history': 2.5,
|
430
|
+
'option/usdc/openapi/private/v1/execution-list': 2.5,
|
431
|
+
'option/usdc/openapi/private/v1/query-transaction-log': 2.5,
|
432
|
+
'option/usdc/openapi/private/v1/query-wallet-balance': 2.5,
|
433
|
+
'option/usdc/openapi/private/v1/query-asset-info': 2.5,
|
434
|
+
'option/usdc/openapi/private/v1/query-margin-info': 2.5,
|
435
|
+
'option/usdc/openapi/private/v1/query-position': 2.5,
|
436
|
+
'option/usdc/openapi/private/v1/query-delivery-list': 2.5,
|
437
|
+
'option/usdc/openapi/private/v1/query-position-exp-date': 2.5,
|
438
|
+
'option/usdc/openapi/private/v1/mmp-modify': 2.5,
|
439
|
+
'option/usdc/openapi/private/v1/mmp-reset': 2.5,
|
440
|
+
// perpetual swap USDC (testnet only)
|
441
|
+
'perpetual/usdc/openapi/private/v1/place-order': 2.5,
|
442
|
+
'perpetual/usdc/openapi/private/v1/replace-order': 2.5,
|
443
|
+
'perpetual/usdc/openapi/private/v1/cancel-order': 2.5,
|
444
|
+
'perpetual/usdc/openapi/private/v1/cancel-all': 2.5,
|
445
|
+
'perpetual/usdc/openapi/private/v1/position/leverage/save': 2.5,
|
446
|
+
'option/usdc/openapi/private/v1/session-settlement': 2.5,
|
447
|
+
'perpetual/usdc/openapi/public/v1/risk-limit/list': 2.5,
|
448
|
+
'perpetual/usdc/openapi/private/v1/position/set-risk-limit': 2.5,
|
449
|
+
},
|
450
|
+
'delete': {
|
451
|
+
// spot
|
452
|
+
'spot/v1/order': 2.5,
|
453
|
+
'spot/v1/order/fast': 2.5,
|
454
|
+
'spot/order/batch-cancel': 2.5,
|
455
|
+
'spot/order/batch-fast-cancel': 2.5,
|
456
|
+
'spot/order/batch-cancel-by-ids': 2.5,
|
457
|
+
},
|
458
|
+
// outdated endpoints -------------------------------------
|
459
|
+
'linear': {
|
460
|
+
'get': [
|
461
|
+
'order/list',
|
462
|
+
'order/search',
|
463
|
+
'stop-order/list',
|
464
|
+
'stop-order/search',
|
465
|
+
'position/list',
|
466
|
+
'trade/execution/list',
|
467
|
+
'trade/closed-pnl/list',
|
468
|
+
'funding/predicted-funding',
|
469
|
+
'funding/prev-funding',
|
470
|
+
],
|
471
|
+
'post': [
|
472
|
+
'order/create',
|
473
|
+
'order/cancel',
|
474
|
+
'order/cancel-all',
|
475
|
+
'order/replace',
|
476
|
+
'stop-order/create',
|
477
|
+
'stop-order/cancel',
|
478
|
+
'stop-order/cancel-all',
|
479
|
+
'stop-order/replace',
|
480
|
+
'position/set-auto-add-margin',
|
481
|
+
'position/switch-isolated',
|
482
|
+
'position/switch-mode',
|
483
|
+
'tpsl/switch-mode',
|
484
|
+
'position/add-margin',
|
485
|
+
'position/set-leverage',
|
486
|
+
'position/trading-stop',
|
487
|
+
'position/set-risk',
|
488
|
+
],
|
489
|
+
},
|
490
|
+
},
|
491
|
+
},
|
492
|
+
'httpExceptions': {
|
493
|
+
'403': RateLimitExceeded, // Forbidden -- You request too many times
|
494
|
+
},
|
495
|
+
'exceptions': {
|
496
|
+
'exact': {
|
497
|
+
'-2015': AuthenticationError, // Invalid API-key, IP, or permissions for action.
|
498
|
+
'10001': BadRequest, // parameter error
|
499
|
+
'10002': InvalidNonce, // request expired, check your timestamp and recv_window
|
500
|
+
'10003': AuthenticationError, // Invalid apikey
|
501
|
+
'10004': AuthenticationError, // invalid sign
|
502
|
+
'10005': PermissionDenied, // permission denied for current apikey
|
503
|
+
'10006': RateLimitExceeded, // too many requests
|
504
|
+
'10007': AuthenticationError, // api_key not found in your request parameters
|
505
|
+
'10010': PermissionDenied, // request ip mismatch
|
506
|
+
'10017': BadRequest, // request path not found or request method is invalid
|
507
|
+
'10018': RateLimitExceeded, // exceed ip rate limit
|
508
|
+
'20001': OrderNotFound, // Order not exists
|
509
|
+
'20003': InvalidOrder, // missing parameter side
|
510
|
+
'20004': InvalidOrder, // invalid parameter side
|
511
|
+
'20005': InvalidOrder, // missing parameter symbol
|
512
|
+
'20006': InvalidOrder, // invalid parameter symbol
|
513
|
+
'20007': InvalidOrder, // missing parameter order_type
|
514
|
+
'20008': InvalidOrder, // invalid parameter order_type
|
515
|
+
'20009': InvalidOrder, // missing parameter qty
|
516
|
+
'20010': InvalidOrder, // qty must be greater than 0
|
517
|
+
'20011': InvalidOrder, // qty must be an integer
|
518
|
+
'20012': InvalidOrder, // qty must be greater than zero and less than 1 million
|
519
|
+
'20013': InvalidOrder, // missing parameter price
|
520
|
+
'20014': InvalidOrder, // price must be greater than 0
|
521
|
+
'20015': InvalidOrder, // missing parameter time_in_force
|
522
|
+
'20016': InvalidOrder, // invalid value for parameter time_in_force
|
523
|
+
'20017': InvalidOrder, // missing parameter order_id
|
524
|
+
'20018': InvalidOrder, // invalid date format
|
525
|
+
'20019': InvalidOrder, // missing parameter stop_px
|
526
|
+
'20020': InvalidOrder, // missing parameter base_price
|
527
|
+
'20021': InvalidOrder, // missing parameter stop_order_id
|
528
|
+
'20022': BadRequest, // missing parameter leverage
|
529
|
+
'20023': BadRequest, // leverage must be a number
|
530
|
+
'20031': BadRequest, // leverage must be greater than zero
|
531
|
+
'20070': BadRequest, // missing parameter margin
|
532
|
+
'20071': BadRequest, // margin must be greater than zero
|
533
|
+
'20084': BadRequest, // order_id or order_link_id is required
|
534
|
+
'30001': BadRequest, // order_link_id is repeated
|
535
|
+
'30003': InvalidOrder, // qty must be more than the minimum allowed
|
536
|
+
'30004': InvalidOrder, // qty must be less than the maximum allowed
|
537
|
+
'30005': InvalidOrder, // price exceeds maximum allowed
|
538
|
+
'30007': InvalidOrder, // price exceeds minimum allowed
|
539
|
+
'30008': InvalidOrder, // invalid order_type
|
540
|
+
'30009': ExchangeError, // no position found
|
541
|
+
'30010': InsufficientFunds, // insufficient wallet balance
|
542
|
+
'30011': PermissionDenied, // operation not allowed as position is undergoing liquidation
|
543
|
+
'30012': PermissionDenied, // operation not allowed as position is undergoing ADL
|
544
|
+
'30013': PermissionDenied, // position is in liq or adl status
|
545
|
+
'30014': InvalidOrder, // invalid closing order, qty should not greater than size
|
546
|
+
'30015': InvalidOrder, // invalid closing order, side should be opposite
|
547
|
+
'30016': ExchangeError, // TS and SL must be cancelled first while closing position
|
548
|
+
'30017': InvalidOrder, // estimated fill price cannot be lower than current Buy liq_price
|
549
|
+
'30018': InvalidOrder, // estimated fill price cannot be higher than current Sell liq_price
|
550
|
+
'30019': InvalidOrder, // cannot attach TP/SL params for non-zero position when placing non-opening position order
|
551
|
+
'30020': InvalidOrder, // position already has TP/SL params
|
552
|
+
'30021': InvalidOrder, // cannot afford estimated position_margin
|
553
|
+
'30022': InvalidOrder, // estimated buy liq_price cannot be higher than current mark_price
|
554
|
+
'30023': InvalidOrder, // estimated sell liq_price cannot be lower than current mark_price
|
555
|
+
'30024': InvalidOrder, // cannot set TP/SL/TS for zero-position
|
556
|
+
'30025': InvalidOrder, // trigger price should bigger than 10% of last price
|
557
|
+
'30026': InvalidOrder, // price too high
|
558
|
+
'30027': InvalidOrder, // price set for Take profit should be higher than Last Traded Price
|
559
|
+
'30028': InvalidOrder, // price set for Stop loss should be between Liquidation price and Last Traded Price
|
560
|
+
'30029': InvalidOrder, // price set for Stop loss should be between Last Traded Price and Liquidation price
|
561
|
+
'30030': InvalidOrder, // price set for Take profit should be lower than Last Traded Price
|
562
|
+
'30031': InsufficientFunds, // insufficient available balance for order cost
|
563
|
+
'30032': InvalidOrder, // order has been filled or cancelled
|
564
|
+
'30033': RateLimitExceeded, // The number of stop orders exceeds maximum limit allowed
|
565
|
+
'30034': OrderNotFound, // no order found
|
566
|
+
'30035': RateLimitExceeded, // too fast to cancel
|
567
|
+
'30036': ExchangeError, // the expected position value after order execution exceeds the current risk limit
|
568
|
+
'30037': InvalidOrder, // order already cancelled
|
569
|
+
'30041': ExchangeError, // no position found
|
570
|
+
'30042': InsufficientFunds, // insufficient wallet balance
|
571
|
+
'30043': InvalidOrder, // operation not allowed as position is undergoing liquidation
|
572
|
+
'30044': InvalidOrder, // operation not allowed as position is undergoing AD
|
573
|
+
'30045': InvalidOrder, // operation not allowed as position is not normal status
|
574
|
+
'30049': InsufficientFunds, // insufficient available balance
|
575
|
+
'30050': ExchangeError, // any adjustments made will trigger immediate liquidation
|
576
|
+
'30051': ExchangeError, // due to risk limit, cannot adjust leverage
|
577
|
+
'30052': ExchangeError, // leverage can not less than 1
|
578
|
+
'30054': ExchangeError, // position margin is invalid
|
579
|
+
'30057': ExchangeError, // requested quantity of contracts exceeds risk limit
|
580
|
+
'30063': ExchangeError, // reduce-only rule not satisfied
|
581
|
+
'30067': InsufficientFunds, // insufficient available balance
|
582
|
+
'30068': ExchangeError, // exit value must be positive
|
583
|
+
'30074': InvalidOrder, // can't create the stop order, because you expect the order will be triggered when the LastPrice(or IndexPrice、 MarkPrice, determined by trigger_by) is raising to stop_px, but the LastPrice(or IndexPrice、 MarkPrice) is already equal to or greater than stop_px, please adjust base_price or stop_px
|
584
|
+
'30075': InvalidOrder, // can't create the stop order, because you expect the order will be triggered when the LastPrice(or IndexPrice、 MarkPrice, determined by trigger_by) is falling to stop_px, but the LastPrice(or IndexPrice、 MarkPrice) is already equal to or less than stop_px, please adjust base_price or stop_px
|
585
|
+
'30078': ExchangeError, // {"ret_code":30078,"ret_msg":"","ext_code":"","ext_info":"","result":null,"time_now":"1644853040.916000","rate_limit_status":73,"rate_limit_reset_ms":1644853040912,"rate_limit":75}
|
586
|
+
// '30084': BadRequest, // Isolated not modified, see handleErrors below
|
587
|
+
'33004': AuthenticationError, // apikey already expired
|
588
|
+
'34026': ExchangeError, // the limit is no change
|
589
|
+
'130021': InsufficientFunds, // {"ret_code":130021,"ret_msg":"orderfix price failed for CannotAffordOrderCost.","ext_code":"","ext_info":"","result":null,"time_now":"1644588250.204878","rate_limit_status":98,"rate_limit_reset_ms":1644588250200,"rate_limit":100}
|
590
|
+
},
|
591
|
+
'broad': {
|
592
|
+
'unknown orderInfo': OrderNotFound, // {"ret_code":-1,"ret_msg":"unknown orderInfo","ext_code":"","ext_info":"","result":null,"time_now":"1584030414.005545","rate_limit_status":99,"rate_limit_reset_ms":1584030414003,"rate_limit":100}
|
593
|
+
'invalid api_key': AuthenticationError, // {"ret_code":10003,"ret_msg":"invalid api_key","ext_code":"","ext_info":"","result":null,"time_now":"1599547085.415797"}
|
594
|
+
},
|
595
|
+
},
|
596
|
+
'precisionMode': TICK_SIZE,
|
597
|
+
'options': {
|
598
|
+
'marketTypes': {
|
599
|
+
'BTC/USDT': 'linear',
|
600
|
+
'ETH/USDT': 'linear',
|
601
|
+
'BNB/USDT': 'linear',
|
602
|
+
'ADA/USDT': 'linear',
|
603
|
+
'DOGE/USDT': 'linear',
|
604
|
+
'XRP/USDT': 'linear',
|
605
|
+
'DOT/USDT': 'linear',
|
606
|
+
'UNI/USDT': 'linear',
|
607
|
+
'BCH/USDT': 'linear',
|
608
|
+
'LTC/USDT': 'linear',
|
609
|
+
'SOL/USDT': 'linear',
|
610
|
+
'LINK/USDT': 'linear',
|
611
|
+
'MATIC/USDT': 'linear',
|
612
|
+
'ETC/USDT': 'linear',
|
613
|
+
'FIL/USDT': 'linear',
|
614
|
+
'EOS/USDT': 'linear',
|
615
|
+
'AAVE/USDT': 'linear',
|
616
|
+
'XTZ/USDT': 'linear',
|
617
|
+
'SUSHI/USDT': 'linear',
|
618
|
+
'XEM/USDT': 'linear',
|
619
|
+
'BTC/USD': 'inverse',
|
620
|
+
'ETH/USD': 'inverse',
|
621
|
+
'EOS/USD': 'inverse',
|
622
|
+
'XRP/USD': 'inverse',
|
623
|
+
},
|
624
|
+
'defaultType': 'linear', // linear, inverse, futures
|
625
|
+
//
|
626
|
+
// ^
|
627
|
+
// |
|
628
|
+
// | this will be replaced with the following soon |
|
629
|
+
// |
|
630
|
+
// v
|
631
|
+
//
|
632
|
+
// 'defaultType': 'swap', // swap, spot, future, option
|
633
|
+
'code': 'BTC',
|
634
|
+
'cancelAllOrders': {
|
635
|
+
// 'method': 'v2PrivatePostOrderCancelAll', // v2PrivatePostStopOrderCancelAll
|
636
|
+
},
|
637
|
+
'recvWindow': 5 * 1000, // 5 sec default
|
638
|
+
'timeDifference': 0, // the difference between system clock and exchange server clock
|
639
|
+
'adjustForTimeDifference': false, // controls the adjustment logic upon instantiation
|
640
|
+
},
|
641
|
+
'fees': {
|
642
|
+
'trading': {
|
643
|
+
'tierBased': false,
|
644
|
+
'percentage': true,
|
645
|
+
'taker': 0.00075,
|
646
|
+
'maker': -0.00025,
|
647
|
+
},
|
648
|
+
'funding': {
|
649
|
+
'tierBased': false,
|
650
|
+
'percentage': false,
|
651
|
+
'withdraw': {},
|
652
|
+
'deposit': {},
|
653
|
+
},
|
654
|
+
},
|
655
|
+
});
|
656
|
+
}
|
657
|
+
|
658
|
+
nonce () {
|
659
|
+
return this.milliseconds () - this.options['timeDifference'];
|
660
|
+
}
|
661
|
+
|
662
|
+
async fetchTime (params = {}) {
|
663
|
+
const response = await this.publicGetV2PublicTime (params);
|
664
|
+
//
|
665
|
+
// {
|
666
|
+
// ret_code: 0,
|
667
|
+
// ret_msg: 'OK',
|
668
|
+
// ext_code: '',
|
669
|
+
// ext_info: '',
|
670
|
+
// result: {},
|
671
|
+
// time_now: '1583933682.448826'
|
672
|
+
// }
|
673
|
+
//
|
674
|
+
return this.safeTimestamp (response, 'time_now');
|
675
|
+
}
|
676
|
+
|
677
|
+
async fetchMarkets (params = {}) {
|
678
|
+
if (this.options['adjustForTimeDifference']) {
|
679
|
+
await this.loadTimeDifference ();
|
680
|
+
}
|
681
|
+
const response = await this.publicGetV2PublicSymbols (params);
|
682
|
+
//
|
683
|
+
// linear swaps and inverse swaps and futures
|
684
|
+
// const swapsResponse = await this.publicGetV2PublicSymbols (params);
|
685
|
+
//
|
686
|
+
// {
|
687
|
+
// "ret_code":0,
|
688
|
+
// "ret_msg":"OK",
|
689
|
+
// "ext_code":"",
|
690
|
+
// "ext_info":"",
|
691
|
+
// "result":[
|
692
|
+
// // inverse swap
|
693
|
+
// {
|
694
|
+
// "name":"BTCUSD",
|
695
|
+
// "alias":"BTCUSD",
|
696
|
+
// "status":"Trading",
|
697
|
+
// "base_currency":"BTC",
|
698
|
+
// "quote_currency":"USD",
|
699
|
+
// "price_scale":2,
|
700
|
+
// "taker_fee":"0.00075",
|
701
|
+
// "maker_fee":"-0.00025",
|
702
|
+
// "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"},
|
703
|
+
// "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
|
704
|
+
// "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1}
|
705
|
+
// },
|
706
|
+
// // linear swap
|
707
|
+
// {
|
708
|
+
// "name":"BTCUSDT",
|
709
|
+
// "alias":"BTCUSDT",
|
710
|
+
// "status":"Trading",
|
711
|
+
// "base_currency":"BTC",
|
712
|
+
// "quote_currency":"USDT",
|
713
|
+
// "price_scale":2,
|
714
|
+
// "taker_fee":"0.00075",
|
715
|
+
// "maker_fee":"-0.00025",
|
716
|
+
// "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"},
|
717
|
+
// "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
|
718
|
+
// "lot_size_filter":{"max_trading_qty":100,"min_trading_qty":0.001, "qty_step":0.001}
|
719
|
+
// },
|
720
|
+
// // inverse futures
|
721
|
+
// {
|
722
|
+
// "name":"BTCUSDM22",
|
723
|
+
// "alias":"BTCUSD0624",
|
724
|
+
// "status":"Trading",
|
725
|
+
// "base_currency":"BTC",
|
726
|
+
// "quote_currency":"USD",
|
727
|
+
// "price_scale":2,
|
728
|
+
// "taker_fee":"0.00075",
|
729
|
+
// "maker_fee":"-0.00025",
|
730
|
+
// "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"},
|
731
|
+
// "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
|
732
|
+
// "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1}
|
733
|
+
// },
|
734
|
+
// {
|
735
|
+
// "name":"BTCUSDH22",
|
736
|
+
// "alias":"BTCUSD0325",
|
737
|
+
// "status":"Trading",
|
738
|
+
// "base_currency":"BTC",
|
739
|
+
// "quote_currency":"USD",
|
740
|
+
// "price_scale":2,
|
741
|
+
// "taker_fee":"0.00075",
|
742
|
+
// "maker_fee":"-0.00025",
|
743
|
+
// "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"}
|
744
|
+
// "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
|
745
|
+
// "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1}
|
746
|
+
// }
|
747
|
+
// ],
|
748
|
+
// "time_now":"1642369942.072113"
|
749
|
+
// }
|
750
|
+
//
|
751
|
+
// spot markets
|
752
|
+
// const spotResponse = await this.publicGetSpotV1Symbols (params);
|
753
|
+
//
|
754
|
+
// {
|
755
|
+
// "ret_code":0,
|
756
|
+
// "ret_msg":"",
|
757
|
+
// "ext_code":null,
|
758
|
+
// "ext_info":null,
|
759
|
+
// "result":[
|
760
|
+
// {
|
761
|
+
// "name":"BTCUSDT",
|
762
|
+
// "alias":"BTCUSDT",
|
763
|
+
// "baseCurrency":"BTC",
|
764
|
+
// "quoteCurrency":"USDT",
|
765
|
+
// "basePrecision":"0.000001",
|
766
|
+
// "quotePrecision":"0.00000001",
|
767
|
+
// "minTradeQuantity":"0.000158",
|
768
|
+
// "minTradeAmount":"10",
|
769
|
+
// "maxTradeQuantity":"4",
|
770
|
+
// "maxTradeAmount":"100000",
|
771
|
+
// "minPricePrecision":"0.01",
|
772
|
+
// "category":1,
|
773
|
+
// "showStatus":true
|
774
|
+
// },
|
775
|
+
// ]
|
776
|
+
// }
|
777
|
+
//
|
778
|
+
// USDC linear options response
|
779
|
+
// const linearOptionsResponse = await this.publicGetOptionUsdcOpenapiPublicV1Symbols (params);
|
780
|
+
//
|
781
|
+
// {
|
782
|
+
// "retCode":0,
|
783
|
+
// "retMsg":"success",
|
784
|
+
// "result":{
|
785
|
+
// "resultTotalSize":424,
|
786
|
+
// "cursor":"0%2C500",
|
787
|
+
// "dataList":[
|
788
|
+
// {
|
789
|
+
// "symbol":"BTC-24JUN22-300000-C",
|
790
|
+
// "status":"ONLINE",
|
791
|
+
// "baseCoin":"BTC",
|
792
|
+
// "quoteCoin":"USD",
|
793
|
+
// "settleCoin":"USDC",
|
794
|
+
// "takerFee":"0.0003",
|
795
|
+
// "makerFee":"0.0003",
|
796
|
+
// "minLeverage":"",
|
797
|
+
// "maxLeverage":"",
|
798
|
+
// "leverageStep":"",
|
799
|
+
// "minOrderPrice":"0.5",
|
800
|
+
// "maxOrderPrice":"10000000",
|
801
|
+
// "minOrderSize":"0.01",
|
802
|
+
// "maxOrderSize":"200",
|
803
|
+
// "tickSize":"0.5",
|
804
|
+
// "minOrderSizeIncrement":"0.01",
|
805
|
+
// "basicDeliveryFeeRate":"0.00015",
|
806
|
+
// "deliveryTime":"1656057600000"
|
807
|
+
// },
|
808
|
+
// {
|
809
|
+
// "symbol":"BTC-24JUN22-300000-P",
|
810
|
+
// "status":"ONLINE",
|
811
|
+
// "baseCoin":"BTC",
|
812
|
+
// "quoteCoin":"USD",
|
813
|
+
// "settleCoin":"USDC",
|
814
|
+
// "takerFee":"0.0003",
|
815
|
+
// "makerFee":"0.0003",
|
816
|
+
// "minLeverage":"",
|
817
|
+
// "maxLeverage":"",
|
818
|
+
// "leverageStep":"",
|
819
|
+
// "minOrderPrice":"0.5",
|
820
|
+
// "maxOrderPrice":"10000000",
|
821
|
+
// "minOrderSize":"0.01",
|
822
|
+
// "maxOrderSize":"200",
|
823
|
+
// "tickSize":"0.5",
|
824
|
+
// "minOrderSizeIncrement":"0.01",
|
825
|
+
// "basicDeliveryFeeRate":"0.00015",
|
826
|
+
// "deliveryTime":"1656057600000"
|
827
|
+
// },
|
828
|
+
// ]
|
829
|
+
// }
|
830
|
+
// }
|
831
|
+
//
|
832
|
+
// USDC linear perpetual swaps
|
833
|
+
// const usdcLinearPerpetualSwaps = await this.publicGetPerpetualUsdcOpenapiPublicV1Symbols (params);
|
834
|
+
//
|
835
|
+
// {
|
836
|
+
// "retCode":0,
|
837
|
+
// "retMsg":"",
|
838
|
+
// "result":[
|
839
|
+
// {
|
840
|
+
// "symbol":"BTCPERP",
|
841
|
+
// "status":"ONLINE",
|
842
|
+
// "baseCoin":"BTC",
|
843
|
+
// "quoteCoin":"USD",
|
844
|
+
// "takerFeeRate":"0.00075",
|
845
|
+
// "makerFeeRate":"-0.00025",
|
846
|
+
// "minLeverage":"1",
|
847
|
+
// "maxLeverage":"100",
|
848
|
+
// "leverageStep":"0.01",
|
849
|
+
// "minPrice":"0.50",
|
850
|
+
// "maxPrice":"999999.00",
|
851
|
+
// "tickSize":"0.50",
|
852
|
+
// "maxTradingQty":"5.000",
|
853
|
+
// "minTradingQty":"0.001",
|
854
|
+
// "qtyStep":"0.001",
|
855
|
+
// "deliveryFeeRate":"",
|
856
|
+
// "deliveryTime":"0"
|
857
|
+
// }
|
858
|
+
// ]
|
859
|
+
// }
|
860
|
+
//
|
861
|
+
const markets = this.safeValue (response, 'result', []);
|
862
|
+
const options = this.safeValue (this.options, 'fetchMarkets', {});
|
863
|
+
const linearQuoteCurrencies = this.safeValue (options, 'linear', { 'USDT': true });
|
864
|
+
const result = [];
|
865
|
+
for (let i = 0; i < markets.length; i++) {
|
866
|
+
const market = markets[i];
|
867
|
+
const id = this.safeString2 (market, 'name', 'symbol');
|
868
|
+
const baseId = this.safeString2 (market, 'base_currency', 'baseCoin');
|
869
|
+
const quoteId = this.safeString2 (market, 'quote_currency', 'quoteCoin');
|
870
|
+
let settleId = this.safeString (market, 'settleCoin');
|
871
|
+
const base = this.safeCurrencyCode (baseId);
|
872
|
+
const quote = this.safeCurrencyCode (quoteId);
|
873
|
+
let settle = this.safeCurrencyCode (settleId);
|
874
|
+
const linear = (quote in linearQuoteCurrencies);
|
875
|
+
let symbol = base + '/' + quote;
|
876
|
+
const baseQuote = base + quote;
|
877
|
+
let type = 'swap';
|
878
|
+
if (baseQuote !== id) {
|
879
|
+
type = 'future';
|
880
|
+
}
|
881
|
+
const lotSizeFilter = this.safeValue (market, 'lot_size_filter', {});
|
882
|
+
const priceFilter = this.safeValue (market, 'price_filter', {});
|
883
|
+
const leverage = this.safeValue (market, 'leverage_filter', {});
|
884
|
+
const status = this.safeString (market, 'status');
|
885
|
+
let active = undefined;
|
886
|
+
if (status !== undefined) {
|
887
|
+
active = (status === 'Trading');
|
888
|
+
}
|
889
|
+
const swap = (type === 'swap');
|
890
|
+
const future = (type === 'future');
|
891
|
+
const option = (type === 'option');
|
892
|
+
const contract = swap || future || option;
|
893
|
+
let expiry = undefined;
|
894
|
+
let expiryDatetime = undefined;
|
895
|
+
let strike = undefined;
|
896
|
+
let optionType = undefined;
|
897
|
+
if (contract) {
|
898
|
+
if (settle === undefined) {
|
899
|
+
settleId = linear ? quoteId : baseId;
|
900
|
+
settle = this.safeCurrencyCode (settleId);
|
901
|
+
}
|
902
|
+
symbol = symbol + ':' + settle;
|
903
|
+
if (future) {
|
904
|
+
const alias = this.safeString (market, 'alias');
|
905
|
+
const shortDate = alias.slice (-4);
|
906
|
+
const date = this.iso8601 (this.milliseconds ());
|
907
|
+
const splitDate = date.split ('-');
|
908
|
+
const year = splitDate[0];
|
909
|
+
const expiryMonth = shortDate.slice (0, 2);
|
910
|
+
const expiryDay = shortDate.slice (2, 4);
|
911
|
+
expiryDatetime = year + '-' + expiryMonth + '-' + expiryDay + 'T00:00:00Z';
|
912
|
+
expiry = this.parse8601 (expiryDatetime);
|
913
|
+
symbol = symbol + '-' + this.yymmdd (expiry);
|
914
|
+
} else if (option) {
|
915
|
+
expiry = this.safeInteger (market, 'deliveryTime');
|
916
|
+
expiryDatetime = this.iso8601 (expiry);
|
917
|
+
const splitId = this.split (id, '-');
|
918
|
+
strike = this.safeString (splitId, 2);
|
919
|
+
const optionLetter = this.safeString (splitId, 3);
|
920
|
+
symbol = symbol + '-' + this.yymmdd (expiry) + ':' + strike + ':' + optionLetter;
|
921
|
+
if (optionLetter === 'P') {
|
922
|
+
optionType = 'put';
|
923
|
+
} else if (optionLetter === 'C') {
|
924
|
+
optionType = 'call';
|
925
|
+
}
|
926
|
+
}
|
927
|
+
}
|
928
|
+
result.push ({
|
929
|
+
'id': id,
|
930
|
+
'symbol': symbol,
|
931
|
+
'base': base,
|
932
|
+
'quote': quote,
|
933
|
+
'settle': settle,
|
934
|
+
'baseId': baseId,
|
935
|
+
'quoteId': quoteId,
|
936
|
+
'settleId': settleId,
|
937
|
+
'type': type,
|
938
|
+
'spot': (type === 'spot'),
|
939
|
+
'margin': undefined, // todo
|
940
|
+
'swap': swap,
|
941
|
+
'future': future,
|
942
|
+
'futures': future, // Deprecated, use future
|
943
|
+
'option': option,
|
944
|
+
'active': active,
|
945
|
+
'contract': contract,
|
946
|
+
'linear': linear,
|
947
|
+
'inverse': !linear,
|
948
|
+
'taker': this.safeNumber (market, 'taker_fee'),
|
949
|
+
'maker': this.safeNumber (market, 'maker_fee'),
|
950
|
+
'contractSize': undefined, // todo
|
951
|
+
'expiry': expiry,
|
952
|
+
'expiryDatetime': expiryDatetime,
|
953
|
+
'strike': strike,
|
954
|
+
'optionType': optionType,
|
955
|
+
'precision': {
|
956
|
+
'amount': this.safeNumber (lotSizeFilter, 'qty_step'),
|
957
|
+
'price': this.safeNumber (priceFilter, 'tick_size'),
|
958
|
+
},
|
959
|
+
'limits': {
|
960
|
+
'leverage': {
|
961
|
+
'min': this.parseNumber ('1'),
|
962
|
+
'max': this.safeNumber (leverage, 'max_leverage', 1),
|
963
|
+
},
|
964
|
+
'amount': {
|
965
|
+
'min': this.safeNumber (lotSizeFilter, 'min_trading_qty'),
|
966
|
+
'max': this.safeNumber (lotSizeFilter, 'max_trading_qty'),
|
967
|
+
},
|
968
|
+
'price': {
|
969
|
+
'min': this.safeNumber (priceFilter, 'min_price'),
|
970
|
+
'max': this.safeNumber (priceFilter, 'max_price'),
|
971
|
+
},
|
972
|
+
'cost': {
|
973
|
+
'min': undefined,
|
974
|
+
'max': undefined,
|
975
|
+
},
|
976
|
+
},
|
977
|
+
'info': market,
|
978
|
+
});
|
979
|
+
}
|
980
|
+
return result;
|
981
|
+
}
|
982
|
+
|
983
|
+
parseTicker (ticker, market = undefined) {
|
984
|
+
//
|
985
|
+
// fetchTicker
|
986
|
+
//
|
987
|
+
// {
|
988
|
+
// symbol: 'BTCUSD',
|
989
|
+
// bid_price: '7680',
|
990
|
+
// ask_price: '7680.5',
|
991
|
+
// last_price: '7680.00',
|
992
|
+
// last_tick_direction: 'MinusTick',
|
993
|
+
// prev_price_24h: '7870.50',
|
994
|
+
// price_24h_pcnt: '-0.024204',
|
995
|
+
// high_price_24h: '8035.00',
|
996
|
+
// low_price_24h: '7671.00',
|
997
|
+
// prev_price_1h: '7780.00',
|
998
|
+
// price_1h_pcnt: '-0.012853',
|
999
|
+
// mark_price: '7683.27',
|
1000
|
+
// index_price: '7682.74',
|
1001
|
+
// open_interest: 188829147,
|
1002
|
+
// open_value: '23670.06',
|
1003
|
+
// total_turnover: '25744224.90',
|
1004
|
+
// turnover_24h: '102997.83',
|
1005
|
+
// total_volume: 225448878806,
|
1006
|
+
// volume_24h: 809919408,
|
1007
|
+
// funding_rate: '0.0001',
|
1008
|
+
// predicted_funding_rate: '0.0001',
|
1009
|
+
// next_funding_time: '2020-03-12T00:00:00Z',
|
1010
|
+
// countdown_hour: 7
|
1011
|
+
// }
|
1012
|
+
//
|
1013
|
+
const timestamp = undefined;
|
1014
|
+
const marketId = this.safeString (ticker, 'symbol');
|
1015
|
+
const symbol = this.safeSymbol (marketId, market);
|
1016
|
+
const last = this.safeString (ticker, 'last_price');
|
1017
|
+
const open = this.safeString (ticker, 'prev_price_24h');
|
1018
|
+
let percentage = this.safeString (ticker, 'price_24h_pcnt');
|
1019
|
+
percentage = Precise.stringMul (percentage, '100');
|
1020
|
+
const baseVolume = this.safeString (ticker, 'turnover_24h');
|
1021
|
+
const quoteVolume = this.safeString (ticker, 'volume_24h');
|
1022
|
+
return this.safeTicker ({
|
1023
|
+
'symbol': symbol,
|
1024
|
+
'timestamp': timestamp,
|
1025
|
+
'datetime': this.iso8601 (timestamp),
|
1026
|
+
'high': this.safeString (ticker, 'high_price_24h'),
|
1027
|
+
'low': this.safeString (ticker, 'low_price_24h'),
|
1028
|
+
'bid': this.safeString (ticker, 'bid_price'),
|
1029
|
+
'bidVolume': undefined,
|
1030
|
+
'ask': this.safeString (ticker, 'ask_price'),
|
1031
|
+
'askVolume': undefined,
|
1032
|
+
'vwap': undefined,
|
1033
|
+
'open': open,
|
1034
|
+
'close': last,
|
1035
|
+
'last': last,
|
1036
|
+
'previousClose': undefined,
|
1037
|
+
'change': undefined,
|
1038
|
+
'percentage': percentage,
|
1039
|
+
'average': undefined,
|
1040
|
+
'baseVolume': baseVolume,
|
1041
|
+
'quoteVolume': quoteVolume,
|
1042
|
+
'info': ticker,
|
1043
|
+
}, market, false);
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
async fetchTicker (symbol, params = {}) {
|
1047
|
+
await this.loadMarkets ();
|
1048
|
+
const market = this.market (symbol);
|
1049
|
+
const request = {
|
1050
|
+
'symbol': market['id'],
|
1051
|
+
};
|
1052
|
+
const response = await this.publicGetV2PublicTickers (this.extend (request, params));
|
1053
|
+
//
|
1054
|
+
// {
|
1055
|
+
// ret_code: 0,
|
1056
|
+
// ret_msg: 'OK',
|
1057
|
+
// ext_code: '',
|
1058
|
+
// ext_info: '',
|
1059
|
+
// result: [
|
1060
|
+
// {
|
1061
|
+
// symbol: 'BTCUSD',
|
1062
|
+
// bid_price: '7680',
|
1063
|
+
// ask_price: '7680.5',
|
1064
|
+
// last_price: '7680.00',
|
1065
|
+
// last_tick_direction: 'MinusTick',
|
1066
|
+
// prev_price_24h: '7870.50',
|
1067
|
+
// price_24h_pcnt: '-0.024204',
|
1068
|
+
// high_price_24h: '8035.00',
|
1069
|
+
// low_price_24h: '7671.00',
|
1070
|
+
// prev_price_1h: '7780.00',
|
1071
|
+
// price_1h_pcnt: '-0.012853',
|
1072
|
+
// mark_price: '7683.27',
|
1073
|
+
// index_price: '7682.74',
|
1074
|
+
// open_interest: 188829147,
|
1075
|
+
// open_value: '23670.06',
|
1076
|
+
// total_turnover: '25744224.90',
|
1077
|
+
// turnover_24h: '102997.83',
|
1078
|
+
// total_volume: 225448878806,
|
1079
|
+
// volume_24h: 809919408,
|
1080
|
+
// funding_rate: '0.0001',
|
1081
|
+
// predicted_funding_rate: '0.0001',
|
1082
|
+
// next_funding_time: '2020-03-12T00:00:00Z',
|
1083
|
+
// countdown_hour: 7
|
1084
|
+
// }
|
1085
|
+
// ],
|
1086
|
+
// time_now: '1583948195.818255'
|
1087
|
+
// }
|
1088
|
+
//
|
1089
|
+
const result = this.safeValue (response, 'result', []);
|
1090
|
+
const first = this.safeValue (result, 0);
|
1091
|
+
const timestamp = this.safeTimestamp (response, 'time_now');
|
1092
|
+
const ticker = this.parseTicker (first, market);
|
1093
|
+
ticker['timestamp'] = timestamp;
|
1094
|
+
ticker['datetime'] = this.iso8601 (timestamp);
|
1095
|
+
return ticker;
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
async fetchTickers (symbols = undefined, params = {}) {
|
1099
|
+
await this.loadMarkets ();
|
1100
|
+
const response = await this.publicGetV2PublicTickers (params);
|
1101
|
+
//
|
1102
|
+
// {
|
1103
|
+
// ret_code: 0,
|
1104
|
+
// ret_msg: 'OK',
|
1105
|
+
// ext_code: '',
|
1106
|
+
// ext_info: '',
|
1107
|
+
// result: [
|
1108
|
+
// {
|
1109
|
+
// symbol: 'BTCUSD',
|
1110
|
+
// bid_price: '7680',
|
1111
|
+
// ask_price: '7680.5',
|
1112
|
+
// last_price: '7680.00',
|
1113
|
+
// last_tick_direction: 'MinusTick',
|
1114
|
+
// prev_price_24h: '7870.50',
|
1115
|
+
// price_24h_pcnt: '-0.024204',
|
1116
|
+
// high_price_24h: '8035.00',
|
1117
|
+
// low_price_24h: '7671.00',
|
1118
|
+
// prev_price_1h: '7780.00',
|
1119
|
+
// price_1h_pcnt: '-0.012853',
|
1120
|
+
// mark_price: '7683.27',
|
1121
|
+
// index_price: '7682.74',
|
1122
|
+
// open_interest: 188829147,
|
1123
|
+
// open_value: '23670.06',
|
1124
|
+
// total_turnover: '25744224.90',
|
1125
|
+
// turnover_24h: '102997.83',
|
1126
|
+
// total_volume: 225448878806,
|
1127
|
+
// volume_24h: 809919408,
|
1128
|
+
// funding_rate: '0.0001',
|
1129
|
+
// predicted_funding_rate: '0.0001',
|
1130
|
+
// next_funding_time: '2020-03-12T00:00:00Z',
|
1131
|
+
// countdown_hour: 7
|
1132
|
+
// }
|
1133
|
+
// ],
|
1134
|
+
// time_now: '1583948195.818255'
|
1135
|
+
// }
|
1136
|
+
//
|
1137
|
+
const result = this.safeValue (response, 'result', []);
|
1138
|
+
const tickers = {};
|
1139
|
+
for (let i = 0; i < result.length; i++) {
|
1140
|
+
const ticker = this.parseTicker (result[i]);
|
1141
|
+
const symbol = ticker['symbol'];
|
1142
|
+
tickers[symbol] = ticker;
|
1143
|
+
}
|
1144
|
+
return this.filterByArray (tickers, 'symbol', symbols);
|
1145
|
+
}
|
1146
|
+
|
1147
|
+
parseOHLCV (ohlcv, market = undefined) {
|
1148
|
+
//
|
1149
|
+
// inverse perpetual BTC/USD
|
1150
|
+
//
|
1151
|
+
// {
|
1152
|
+
// symbol: 'BTCUSD',
|
1153
|
+
// interval: '1',
|
1154
|
+
// open_time: 1583952540,
|
1155
|
+
// open: '7760.5',
|
1156
|
+
// high: '7764',
|
1157
|
+
// low: '7757',
|
1158
|
+
// close: '7763.5',
|
1159
|
+
// volume: '1259766',
|
1160
|
+
// turnover: '162.32773718999994'
|
1161
|
+
// }
|
1162
|
+
//
|
1163
|
+
// linear perpetual BTC/USDT
|
1164
|
+
//
|
1165
|
+
// {
|
1166
|
+
// "id":143536,
|
1167
|
+
// "symbol":"BTCUSDT",
|
1168
|
+
// "period":"15",
|
1169
|
+
// "start_at":1587883500,
|
1170
|
+
// "volume":1.035,
|
1171
|
+
// "open":7540.5,
|
1172
|
+
// "high":7541,
|
1173
|
+
// "low":7540.5,
|
1174
|
+
// "close":7541
|
1175
|
+
// }
|
1176
|
+
//
|
1177
|
+
return [
|
1178
|
+
this.safeTimestamp2 (ohlcv, 'open_time', 'start_at'),
|
1179
|
+
this.safeNumber (ohlcv, 'open'),
|
1180
|
+
this.safeNumber (ohlcv, 'high'),
|
1181
|
+
this.safeNumber (ohlcv, 'low'),
|
1182
|
+
this.safeNumber (ohlcv, 'close'),
|
1183
|
+
this.safeNumber2 (ohlcv, 'volume', 'turnover'),
|
1184
|
+
];
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1188
|
+
await this.loadMarkets ();
|
1189
|
+
const market = this.market (symbol);
|
1190
|
+
const price = this.safeString (params, 'price');
|
1191
|
+
params = this.omit (params, 'price');
|
1192
|
+
const request = {
|
1193
|
+
'symbol': market['id'],
|
1194
|
+
'interval': this.timeframes[timeframe],
|
1195
|
+
};
|
1196
|
+
const duration = this.parseTimeframe (timeframe);
|
1197
|
+
const now = this.seconds ();
|
1198
|
+
if (since === undefined) {
|
1199
|
+
if (limit === undefined) {
|
1200
|
+
throw new ArgumentsRequired (this.id + ' fetchOHLCV() requires a since argument or a limit argument');
|
1201
|
+
} else {
|
1202
|
+
request['from'] = now - limit * duration;
|
1203
|
+
}
|
1204
|
+
} else {
|
1205
|
+
request['from'] = parseInt (since / 1000);
|
1206
|
+
}
|
1207
|
+
if (limit !== undefined) {
|
1208
|
+
request['limit'] = limit; // max 200, default 200
|
1209
|
+
}
|
1210
|
+
let method = 'publicGetV2PublicKlineList';
|
1211
|
+
if (price === 'mark') {
|
1212
|
+
method = 'publicGetV2PublicMarkPriceKline';
|
1213
|
+
} else if (price === 'index') {
|
1214
|
+
method = 'publicGetV2PublicIndexPriceKline';
|
1215
|
+
} else if (price === 'premiumIndex') {
|
1216
|
+
method = 'publicGetV2PublicPremiumIndexKline';
|
1217
|
+
} else if (market['linear']) {
|
1218
|
+
method = 'publicGetPublicLinearKline';
|
1219
|
+
}
|
1220
|
+
const response = await this[method] (this.extend (request, params));
|
1221
|
+
//
|
1222
|
+
// inverse perpetual BTC/USD
|
1223
|
+
//
|
1224
|
+
// {
|
1225
|
+
// ret_code: 0,
|
1226
|
+
// ret_msg: 'OK',
|
1227
|
+
// ext_code: '',
|
1228
|
+
// ext_info: '',
|
1229
|
+
// result: [
|
1230
|
+
// {
|
1231
|
+
// symbol: 'BTCUSD',
|
1232
|
+
// interval: '1',
|
1233
|
+
// open_time: 1583952540,
|
1234
|
+
// open: '7760.5',
|
1235
|
+
// high: '7764',
|
1236
|
+
// low: '7757',
|
1237
|
+
// close: '7763.5',
|
1238
|
+
// volume: '1259766',
|
1239
|
+
// turnover: '162.32773718999994'
|
1240
|
+
// },
|
1241
|
+
// ],
|
1242
|
+
// time_now: '1583953082.397330'
|
1243
|
+
// }
|
1244
|
+
//
|
1245
|
+
// linear perpetual BTC/USDT
|
1246
|
+
//
|
1247
|
+
// {
|
1248
|
+
// "ret_code":0,
|
1249
|
+
// "ret_msg":"OK",
|
1250
|
+
// "ext_code":"",
|
1251
|
+
// "ext_info":"",
|
1252
|
+
// "result":[
|
1253
|
+
// {
|
1254
|
+
// "id":143536,
|
1255
|
+
// "symbol":"BTCUSDT",
|
1256
|
+
// "period":"15",
|
1257
|
+
// "start_at":1587883500,
|
1258
|
+
// "volume":1.035,
|
1259
|
+
// "open":7540.5,
|
1260
|
+
// "high":7541,
|
1261
|
+
// "low":7540.5,
|
1262
|
+
// "close":7541
|
1263
|
+
// }
|
1264
|
+
// ],
|
1265
|
+
// "time_now":"1587884120.168077"
|
1266
|
+
// }
|
1267
|
+
//
|
1268
|
+
const result = this.safeValue (response, 'result', {});
|
1269
|
+
return this.parseOHLCVs (result, market, timeframe, since, limit);
|
1270
|
+
}
|
1271
|
+
|
1272
|
+
async fetchFundingRate (symbol, params = {}) {
|
1273
|
+
await this.loadMarkets ();
|
1274
|
+
const market = this.market (symbol);
|
1275
|
+
const request = {
|
1276
|
+
'symbol': market['id'],
|
1277
|
+
};
|
1278
|
+
const method = market['linear'] ? 'publicLinearGetFundingPrevFundingRate' : 'v2PublicGetFundingPrevFundingRate';
|
1279
|
+
// TODO const method = market['linear'] ? 'publicGetPublicLinearFundingPrevFundingRate' : 'publicGetV2PublicFundingRate ???? throws ExchangeError';
|
1280
|
+
const response = await this[method] (this.extend (request, params));
|
1281
|
+
//
|
1282
|
+
// {
|
1283
|
+
// "ret_code":0,
|
1284
|
+
// "ret_msg":"OK",
|
1285
|
+
// "ext_code":"",
|
1286
|
+
// "ext_info":"",
|
1287
|
+
// "result":{
|
1288
|
+
// "symbol":"BTCUSDT",
|
1289
|
+
// "funding_rate":0.00006418,
|
1290
|
+
// "funding_rate_timestamp":"2022-03-11T16:00:00.000Z"
|
1291
|
+
// },
|
1292
|
+
// "time_now":"1647040818.724895"
|
1293
|
+
// }
|
1294
|
+
//
|
1295
|
+
// {
|
1296
|
+
// "ret_code":0,
|
1297
|
+
// "ret_msg":"OK",
|
1298
|
+
// "ext_code":"",
|
1299
|
+
// "ext_info":"",
|
1300
|
+
// "result":{
|
1301
|
+
// "symbol":"BTCUSD",
|
1302
|
+
// "funding_rate":"0.00009536",
|
1303
|
+
// "funding_rate_timestamp":1647014400
|
1304
|
+
// },
|
1305
|
+
// "time_now":"1647040852.515724"
|
1306
|
+
// }
|
1307
|
+
//
|
1308
|
+
const result = this.safeValue (response, 'result');
|
1309
|
+
const fundingRate = this.safeNumber (result, 'funding_rate');
|
1310
|
+
let fundingTimestamp = this.parse8601 (this.safeString (result, 'funding_rate_timestamp'));
|
1311
|
+
fundingTimestamp = this.safeTimestamp (result, 'funding_rate_timestamp', fundingTimestamp);
|
1312
|
+
const currentTime = this.milliseconds ();
|
1313
|
+
return {
|
1314
|
+
'info': result,
|
1315
|
+
'symbol': symbol,
|
1316
|
+
'markPrice': undefined,
|
1317
|
+
'indexPrice': undefined,
|
1318
|
+
'interestRate': undefined,
|
1319
|
+
'estimatedSettlePrice': undefined,
|
1320
|
+
'timestamp': currentTime,
|
1321
|
+
'datetime': this.iso8601 (currentTime),
|
1322
|
+
'fundingRate': fundingRate,
|
1323
|
+
'fundingTimestamp': fundingTimestamp,
|
1324
|
+
'fundingDatetime': this.iso8601 (fundingTimestamp),
|
1325
|
+
'nextFundingRate': undefined,
|
1326
|
+
'nextFundingTimestamp': undefined,
|
1327
|
+
'nextFundingDatetime': undefined,
|
1328
|
+
'previousFundingRate': undefined,
|
1329
|
+
'previousFundingTimestamp': undefined,
|
1330
|
+
'previousFundingDatetime': undefined,
|
1331
|
+
};
|
1332
|
+
}
|
1333
|
+
|
1334
|
+
async fetchIndexOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1335
|
+
if (since === undefined && limit === undefined) {
|
1336
|
+
throw new ArgumentsRequired (this.id + ' fetchIndexOHLCV() requires a since argument or a limit argument');
|
1337
|
+
}
|
1338
|
+
const request = {
|
1339
|
+
'price': 'index',
|
1340
|
+
};
|
1341
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
1342
|
+
}
|
1343
|
+
|
1344
|
+
async fetchMarkOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1345
|
+
if (since === undefined && limit === undefined) {
|
1346
|
+
throw new ArgumentsRequired (this.id + ' fetchMarkOHLCV() requires a since argument or a limit argument');
|
1347
|
+
}
|
1348
|
+
const request = {
|
1349
|
+
'price': 'mark',
|
1350
|
+
};
|
1351
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
1352
|
+
}
|
1353
|
+
|
1354
|
+
async fetchPremiumIndexOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1355
|
+
if (since === undefined && limit === undefined) {
|
1356
|
+
throw new ArgumentsRequired (this.id + ' fetchPremiumIndexOHLCV() requires a since argument or a limit argument');
|
1357
|
+
}
|
1358
|
+
const request = {
|
1359
|
+
'price': 'premiumIndex',
|
1360
|
+
};
|
1361
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
1362
|
+
}
|
1363
|
+
|
1364
|
+
parseTrade (trade, market = undefined) {
|
1365
|
+
//
|
1366
|
+
// fetchTrades (public)
|
1367
|
+
//
|
1368
|
+
// {
|
1369
|
+
// "id": "44275042152",
|
1370
|
+
// "symbol": "AAVEUSDT",
|
1371
|
+
// "price": "256.35",
|
1372
|
+
// "qty": "0.1",
|
1373
|
+
// "side": "Buy",
|
1374
|
+
// "time": "2021-11-30T12:46:14.000Z",
|
1375
|
+
// "trade_time_ms": "1638276374312"
|
1376
|
+
// }
|
1377
|
+
//
|
1378
|
+
// fetchMyTrades, fetchOrderTrades (private)
|
1379
|
+
//
|
1380
|
+
// {
|
1381
|
+
// "order_id": "b020b4bc-6fe2-45b5-adbc-dd07794f9746",
|
1382
|
+
// "order_link_id": "",
|
1383
|
+
// "side": "Buy",
|
1384
|
+
// "symbol": "AAVEUSDT",
|
1385
|
+
// "exec_id": "09abe8f0-aea6-514e-942b-7da8cb935120",
|
1386
|
+
// "price": "269.3",
|
1387
|
+
// "order_price": "269.3",
|
1388
|
+
// "order_qty": "0.1",
|
1389
|
+
// "order_type": "Market",
|
1390
|
+
// "fee_rate": "0.00075",
|
1391
|
+
// "exec_price": "256.35",
|
1392
|
+
// "exec_type": "Trade",
|
1393
|
+
// "exec_qty": "0.1",
|
1394
|
+
// "exec_fee": "0.01922625",
|
1395
|
+
// "exec_value": "25.635",
|
1396
|
+
// "leaves_qty": "0",
|
1397
|
+
// "closed_size": "0",
|
1398
|
+
// "last_liquidity_ind": "RemovedLiquidity",
|
1399
|
+
// "trade_time": "1638276374",
|
1400
|
+
// "trade_time_ms": "1638276374312"
|
1401
|
+
// }
|
1402
|
+
//
|
1403
|
+
const id = this.safeString2 (trade, 'id', 'exec_id');
|
1404
|
+
const marketId = this.safeString (trade, 'symbol');
|
1405
|
+
market = this.safeMarket (marketId, market);
|
1406
|
+
const symbol = market['symbol'];
|
1407
|
+
const amountString = this.safeString2 (trade, 'qty', 'exec_qty');
|
1408
|
+
const priceString = this.safeString2 (trade, 'exec_price', 'price');
|
1409
|
+
const costString = this.safeString (trade, 'exec_value');
|
1410
|
+
let timestamp = this.parse8601 (this.safeString (trade, 'time'));
|
1411
|
+
if (timestamp === undefined) {
|
1412
|
+
timestamp = this.safeInteger (trade, 'trade_time_ms');
|
1413
|
+
}
|
1414
|
+
const side = this.safeStringLower (trade, 'side');
|
1415
|
+
const lastLiquidityInd = this.safeString (trade, 'last_liquidity_ind');
|
1416
|
+
const takerOrMaker = (lastLiquidityInd === 'AddedLiquidity') ? 'maker' : 'taker';
|
1417
|
+
const feeCostString = this.safeString (trade, 'exec_fee');
|
1418
|
+
let fee = undefined;
|
1419
|
+
if (feeCostString !== undefined) {
|
1420
|
+
const feeCurrencyCode = market['inverse'] ? market['base'] : market['quote'];
|
1421
|
+
fee = {
|
1422
|
+
'cost': feeCostString,
|
1423
|
+
'currency': feeCurrencyCode,
|
1424
|
+
'rate': this.safeString (trade, 'fee_rate'),
|
1425
|
+
};
|
1426
|
+
}
|
1427
|
+
return this.safeTrade ({
|
1428
|
+
'id': id,
|
1429
|
+
'info': trade,
|
1430
|
+
'timestamp': timestamp,
|
1431
|
+
'datetime': this.iso8601 (timestamp),
|
1432
|
+
'symbol': symbol,
|
1433
|
+
'order': this.safeString (trade, 'order_id'),
|
1434
|
+
'type': this.safeStringLower (trade, 'order_type'),
|
1435
|
+
'side': side,
|
1436
|
+
'takerOrMaker': takerOrMaker,
|
1437
|
+
'price': priceString,
|
1438
|
+
'amount': amountString,
|
1439
|
+
'cost': costString,
|
1440
|
+
'fee': fee,
|
1441
|
+
}, market);
|
1442
|
+
}
|
1443
|
+
|
1444
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
1445
|
+
await this.loadMarkets ();
|
1446
|
+
const market = this.market (symbol);
|
1447
|
+
const request = {
|
1448
|
+
'symbol': market['id'],
|
1449
|
+
// 'from': 123, // from id
|
1450
|
+
};
|
1451
|
+
if (limit !== undefined) {
|
1452
|
+
request['count'] = limit; // default 500, max 1000
|
1453
|
+
}
|
1454
|
+
const method = market['linear'] ? 'publicGetPublicLinearRecentTradingRecords' : 'publicGetV2PublicTradingRecords';
|
1455
|
+
const response = await this[method] (this.extend (request, params));
|
1456
|
+
//
|
1457
|
+
// {
|
1458
|
+
// ret_code: 0,
|
1459
|
+
// ret_msg: 'OK',
|
1460
|
+
// ext_code: '',
|
1461
|
+
// ext_info: '',
|
1462
|
+
// result: [
|
1463
|
+
// {
|
1464
|
+
// id: 43785688,
|
1465
|
+
// symbol: 'BTCUSD',
|
1466
|
+
// price: 7786,
|
1467
|
+
// qty: 67,
|
1468
|
+
// side: 'Sell',
|
1469
|
+
// time: '2020-03-11T19:18:30.123Z'
|
1470
|
+
// },
|
1471
|
+
// ],
|
1472
|
+
// time_now: '1583954313.393362'
|
1473
|
+
// }
|
1474
|
+
//
|
1475
|
+
const result = this.safeValue (response, 'result', {});
|
1476
|
+
return this.parseTrades (result, market, since, limit);
|
1477
|
+
}
|
1478
|
+
|
1479
|
+
parseOrderBook (orderbook, symbol, timestamp = undefined, bidsKey = 'Buy', asksKey = 'Sell', priceKey = 'price', amountKey = 'size') {
|
1480
|
+
const bids = [];
|
1481
|
+
const asks = [];
|
1482
|
+
for (let i = 0; i < orderbook.length; i++) {
|
1483
|
+
const bidask = orderbook[i];
|
1484
|
+
const side = this.safeString (bidask, 'side');
|
1485
|
+
if (side === 'Buy') {
|
1486
|
+
bids.push (this.parseBidAsk (bidask, priceKey, amountKey));
|
1487
|
+
} else if (side === 'Sell') {
|
1488
|
+
asks.push (this.parseBidAsk (bidask, priceKey, amountKey));
|
1489
|
+
} else {
|
1490
|
+
throw new ExchangeError (this.id + ' parseOrderBook() encountered an unrecognized bidask format: ' + this.json (bidask));
|
1491
|
+
}
|
1492
|
+
}
|
1493
|
+
return {
|
1494
|
+
'symbol': symbol,
|
1495
|
+
'bids': this.sortBy (bids, 0, true),
|
1496
|
+
'asks': this.sortBy (asks, 0),
|
1497
|
+
'timestamp': timestamp,
|
1498
|
+
'datetime': this.iso8601 (timestamp),
|
1499
|
+
'nonce': undefined,
|
1500
|
+
};
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
1504
|
+
await this.loadMarkets ();
|
1505
|
+
const market = this.market (symbol);
|
1506
|
+
const request = {
|
1507
|
+
'symbol': market['id'],
|
1508
|
+
};
|
1509
|
+
const response = await this.publicGetV2PublicOrderBookL2 (this.extend (request, params));
|
1510
|
+
//
|
1511
|
+
// {
|
1512
|
+
// ret_code: 0,
|
1513
|
+
// ret_msg: 'OK',
|
1514
|
+
// ext_code: '',
|
1515
|
+
// ext_info: '',
|
1516
|
+
// result: [
|
1517
|
+
// { symbol: 'BTCUSD', price: '7767.5', size: 677956, side: 'Buy' },
|
1518
|
+
// { symbol: 'BTCUSD', price: '7767', size: 580690, side: 'Buy' },
|
1519
|
+
// { symbol: 'BTCUSD', price: '7766.5', size: 475252, side: 'Buy' },
|
1520
|
+
// { symbol: 'BTCUSD', price: '7768', size: 330847, side: 'Sell' },
|
1521
|
+
// { symbol: 'BTCUSD', price: '7768.5', size: 97159, side: 'Sell' },
|
1522
|
+
// { symbol: 'BTCUSD', price: '7769', size: 6508, side: 'Sell' },
|
1523
|
+
// ],
|
1524
|
+
// time_now: '1583954829.874823'
|
1525
|
+
// }
|
1526
|
+
//
|
1527
|
+
const result = this.safeValue (response, 'result', []);
|
1528
|
+
const timestamp = this.safeTimestamp (response, 'time_now');
|
1529
|
+
return this.parseOrderBook (result, symbol, timestamp, 'Buy', 'Sell', 'price', 'size');
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
parseBalance (response) {
|
1533
|
+
const result = {
|
1534
|
+
'info': response,
|
1535
|
+
};
|
1536
|
+
const balances = this.safeValue (response, 'result', {});
|
1537
|
+
const currencyIds = Object.keys (balances);
|
1538
|
+
for (let i = 0; i < currencyIds.length; i++) {
|
1539
|
+
const currencyId = currencyIds[i];
|
1540
|
+
const balance = balances[currencyId];
|
1541
|
+
const code = this.safeCurrencyCode (currencyId);
|
1542
|
+
const account = this.account ();
|
1543
|
+
account['free'] = this.safeString (balance, 'available_balance');
|
1544
|
+
account['used'] = this.safeString (balance, 'used_margin');
|
1545
|
+
account['total'] = this.safeString (balance, 'equity');
|
1546
|
+
result[code] = account;
|
1547
|
+
}
|
1548
|
+
return this.safeBalance (result);
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
async fetchBalance (params = {}) {
|
1552
|
+
// note: any funds in the 'spot' account will not be returned or visible from this endpoint
|
1553
|
+
await this.loadMarkets ();
|
1554
|
+
const request = {};
|
1555
|
+
const coin = this.safeString (params, 'coin');
|
1556
|
+
const code = this.safeString (params, 'code');
|
1557
|
+
if (coin !== undefined) {
|
1558
|
+
request['coin'] = coin;
|
1559
|
+
} else if (code !== undefined) {
|
1560
|
+
const currency = this.currency (code);
|
1561
|
+
request['coin'] = currency['id'];
|
1562
|
+
}
|
1563
|
+
const response = await this.v2PrivateGetWalletBalance (this.extend (request, params));
|
1564
|
+
//
|
1565
|
+
// {
|
1566
|
+
// ret_code: 0,
|
1567
|
+
// ret_msg: 'OK',
|
1568
|
+
// ext_code: '',
|
1569
|
+
// ext_info: '',
|
1570
|
+
// result: {
|
1571
|
+
// BTC: {
|
1572
|
+
// equity: 0,
|
1573
|
+
// available_balance: 0,
|
1574
|
+
// used_margin: 0,
|
1575
|
+
// order_margin: 0,
|
1576
|
+
// position_margin: 0,
|
1577
|
+
// occ_closing_fee: 0,
|
1578
|
+
// occ_funding_fee: 0,
|
1579
|
+
// wallet_balance: 0,
|
1580
|
+
// realised_pnl: 0,
|
1581
|
+
// unrealised_pnl: 0,
|
1582
|
+
// cum_realised_pnl: 0,
|
1583
|
+
// given_cash: 0,
|
1584
|
+
// service_cash: 0
|
1585
|
+
// }
|
1586
|
+
// },
|
1587
|
+
// time_now: '1583937810.370020',
|
1588
|
+
// rate_limit_status: 119,
|
1589
|
+
// rate_limit_reset_ms: 1583937810367,
|
1590
|
+
// rate_limit: 120
|
1591
|
+
// }
|
1592
|
+
//
|
1593
|
+
return this.parseBalance (response);
|
1594
|
+
}
|
1595
|
+
|
1596
|
+
parseOrderStatus (status) {
|
1597
|
+
const statuses = {
|
1598
|
+
// basic orders
|
1599
|
+
'Created': 'open',
|
1600
|
+
'Rejected': 'rejected', // order is triggered but failed upon being placed
|
1601
|
+
'New': 'open',
|
1602
|
+
'PartiallyFilled': 'open',
|
1603
|
+
'Filled': 'closed',
|
1604
|
+
'Cancelled': 'canceled',
|
1605
|
+
'PendingCancel': 'canceling', // the engine has received the cancellation but there is no guarantee that it will be successful
|
1606
|
+
// conditional orders
|
1607
|
+
'Active': 'open', // order is triggered and placed successfully
|
1608
|
+
'Untriggered': 'open', // order waits to be triggered
|
1609
|
+
'Triggered': 'closed', // order is triggered
|
1610
|
+
// 'Cancelled': 'canceled', // order is cancelled
|
1611
|
+
// 'Rejected': 'rejected', // order is triggered but fail to be placed
|
1612
|
+
'Deactivated': 'canceled', // conditional order was cancelled before triggering
|
1613
|
+
};
|
1614
|
+
return this.safeString (statuses, status, status);
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
parseTimeInForce (timeInForce) {
|
1618
|
+
const timeInForces = {
|
1619
|
+
'GoodTillCancel': 'GTC',
|
1620
|
+
'ImmediateOrCancel': 'IOC',
|
1621
|
+
'FillOrKill': 'FOK',
|
1622
|
+
'PostOnly': 'PO',
|
1623
|
+
};
|
1624
|
+
return this.safeString (timeInForces, timeInForce, timeInForce);
|
1625
|
+
}
|
1626
|
+
|
1627
|
+
parseOrder (order, market = undefined) {
|
1628
|
+
//
|
1629
|
+
// createOrder
|
1630
|
+
//
|
1631
|
+
// {
|
1632
|
+
// "user_id": 1,
|
1633
|
+
// "order_id": "335fd977-e5a5-4781-b6d0-c772d5bfb95b",
|
1634
|
+
// "symbol": "BTCUSD",
|
1635
|
+
// "side": "Buy",
|
1636
|
+
// "order_type": "Limit",
|
1637
|
+
// "price": 8800,
|
1638
|
+
// "qty": 1,
|
1639
|
+
// "time_in_force": "GoodTillCancel",
|
1640
|
+
// "order_status": "Created",
|
1641
|
+
// "last_exec_time": 0,
|
1642
|
+
// "last_exec_price": 0,
|
1643
|
+
// "leaves_qty": 1,
|
1644
|
+
// "cum_exec_qty": 0, // in contracts, where 1 contract = 1 quote currency unit (USD for inverse contracts)
|
1645
|
+
// "cum_exec_value": 0, // in contract's underlying currency (BTC for inverse contracts)
|
1646
|
+
// "cum_exec_fee": 0,
|
1647
|
+
// "reject_reason": "",
|
1648
|
+
// "order_link_id": "",
|
1649
|
+
// "created_at": "2019-11-30T11:03:43.452Z",
|
1650
|
+
// "updated_at": "2019-11-30T11:03:43.455Z"
|
1651
|
+
// }
|
1652
|
+
//
|
1653
|
+
// fetchOrder
|
1654
|
+
//
|
1655
|
+
// {
|
1656
|
+
// "user_id" : 599946,
|
1657
|
+
// "symbol" : "BTCUSD",
|
1658
|
+
// "side" : "Buy",
|
1659
|
+
// "order_type" : "Limit",
|
1660
|
+
// "price" : "7948",
|
1661
|
+
// "qty" : 10,
|
1662
|
+
// "time_in_force" : "GoodTillCancel",
|
1663
|
+
// "order_status" : "Filled",
|
1664
|
+
// "ext_fields" : {
|
1665
|
+
// "o_req_num" : -1600687220498,
|
1666
|
+
// "xreq_type" : "x_create"
|
1667
|
+
// },
|
1668
|
+
// "last_exec_time" : "1588150113.968422",
|
1669
|
+
// "last_exec_price" : "7948",
|
1670
|
+
// "leaves_qty" : 0,
|
1671
|
+
// "leaves_value" : "0",
|
1672
|
+
// "cum_exec_qty" : 10,
|
1673
|
+
// "cum_exec_value" : "0.00125817",
|
1674
|
+
// "cum_exec_fee" : "-0.00000031",
|
1675
|
+
// "reject_reason" : "",
|
1676
|
+
// "cancel_type" : "",
|
1677
|
+
// "order_link_id" : "",
|
1678
|
+
// "created_at" : "2020-04-29T08:45:24.399146Z",
|
1679
|
+
// "updated_at" : "2020-04-29T08:48:33.968422Z",
|
1680
|
+
// "order_id" : "dd2504b9-0157-406a-99e1-efa522373944"
|
1681
|
+
// }
|
1682
|
+
//
|
1683
|
+
// fetchOrders linear swaps
|
1684
|
+
//
|
1685
|
+
// {
|
1686
|
+
// "order_id":"7917bd70-e7c3-4af5-8147-3285cd99c509",
|
1687
|
+
// "user_id":22919890,
|
1688
|
+
// "symbol":"GMTUSDT",
|
1689
|
+
// "side":"Buy",
|
1690
|
+
// "order_type":"Limit",
|
1691
|
+
// "price":2.9262,
|
1692
|
+
// "qty":50,
|
1693
|
+
// "time_in_force":"GoodTillCancel",
|
1694
|
+
// "order_status":"Filled",
|
1695
|
+
// "last_exec_price":2.9219,
|
1696
|
+
// "cum_exec_qty":50,
|
1697
|
+
// "cum_exec_value":146.095,
|
1698
|
+
// "cum_exec_fee":0.087657,
|
1699
|
+
// "reduce_only":false,
|
1700
|
+
// "close_on_trigger":false,
|
1701
|
+
// "order_link_id":"",
|
1702
|
+
// "created_time":"2022-04-18T17:09:54Z",
|
1703
|
+
// "updated_time":"2022-04-18T17:09:54Z",
|
1704
|
+
// "take_profit":0,
|
1705
|
+
// "stop_loss":0,
|
1706
|
+
// "tp_trigger_by":"UNKNOWN",
|
1707
|
+
// "sl_trigger_by":"UNKNOWN"
|
1708
|
+
// }
|
1709
|
+
//
|
1710
|
+
// conditional order
|
1711
|
+
//
|
1712
|
+
// {
|
1713
|
+
// "user_id":##,
|
1714
|
+
// "symbol":"BTCUSD",
|
1715
|
+
// "side":"Buy",
|
1716
|
+
// "order_type":"Market",
|
1717
|
+
// "price":0,
|
1718
|
+
// "qty":10,
|
1719
|
+
// "time_in_force":"GoodTillCancel",
|
1720
|
+
// "stop_order_type":"Stop",
|
1721
|
+
// "trigger_by":"LastPrice",
|
1722
|
+
// "base_price":11833,
|
1723
|
+
// "order_status":"Untriggered",
|
1724
|
+
// "ext_fields":{
|
1725
|
+
// "stop_order_type":"Stop",
|
1726
|
+
// "trigger_by":"LastPrice",
|
1727
|
+
// "base_price":11833,
|
1728
|
+
// "expected_direction":"Rising",
|
1729
|
+
// "trigger_price":12400,
|
1730
|
+
// "close_on_trigger":true,
|
1731
|
+
// "op_from":"api",
|
1732
|
+
// "remark":"x.x.x.x",
|
1733
|
+
// "o_req_num":0
|
1734
|
+
// },
|
1735
|
+
// "leaves_qty":10,
|
1736
|
+
// "leaves_value":0.00080645,
|
1737
|
+
// "reject_reason":null,
|
1738
|
+
// "cross_seq":-1,
|
1739
|
+
// "created_at":"2020-08-21T09:18:48.000Z",
|
1740
|
+
// "updated_at":"2020-08-21T09:18:48.000Z",
|
1741
|
+
// "trigger_price":12400,
|
1742
|
+
// "stop_order_id":"3f3b54b1-3379-42c7-8510-44f4d9915be0"
|
1743
|
+
// }
|
1744
|
+
//
|
1745
|
+
const marketId = this.safeString (order, 'symbol');
|
1746
|
+
market = this.safeMarket (marketId, market);
|
1747
|
+
const symbol = market['symbol'];
|
1748
|
+
let feeCurrency = undefined;
|
1749
|
+
const timestamp = this.parse8601 (this.safeString2 (order, 'created_at', 'created_time'));
|
1750
|
+
const id = this.safeString2 (order, 'order_id', 'stop_order_id');
|
1751
|
+
const type = this.safeStringLower (order, 'order_type');
|
1752
|
+
let price = undefined;
|
1753
|
+
if (type !== 'market') {
|
1754
|
+
price = this.safeString (order, 'price');
|
1755
|
+
}
|
1756
|
+
const average = this.safeString (order, 'average_price');
|
1757
|
+
const amount = this.safeString (order, 'qty');
|
1758
|
+
const cost = this.safeString (order, 'cum_exec_value');
|
1759
|
+
const filled = this.safeString (order, 'cum_exec_qty');
|
1760
|
+
const remaining = this.safeString (order, 'leaves_qty');
|
1761
|
+
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
1762
|
+
const marketType = this.safeString (marketTypes, symbol);
|
1763
|
+
if (marketType === 'linear') {
|
1764
|
+
feeCurrency = market['quote'];
|
1765
|
+
} else {
|
1766
|
+
feeCurrency = market['base'];
|
1767
|
+
}
|
1768
|
+
let lastTradeTimestamp = this.safeTimestamp (order, 'last_exec_time');
|
1769
|
+
if (lastTradeTimestamp === 0) {
|
1770
|
+
lastTradeTimestamp = undefined;
|
1771
|
+
}
|
1772
|
+
const status = this.parseOrderStatus (this.safeString2 (order, 'order_status', 'stop_order_status'));
|
1773
|
+
const side = this.safeStringLower (order, 'side');
|
1774
|
+
const feeCostString = this.safeString (order, 'cum_exec_fee');
|
1775
|
+
let fee = undefined;
|
1776
|
+
if (feeCostString !== undefined) {
|
1777
|
+
fee = {
|
1778
|
+
'cost': feeCostString,
|
1779
|
+
'currency': feeCurrency,
|
1780
|
+
};
|
1781
|
+
}
|
1782
|
+
let clientOrderId = this.safeString (order, 'order_link_id');
|
1783
|
+
if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {
|
1784
|
+
clientOrderId = undefined;
|
1785
|
+
}
|
1786
|
+
const timeInForce = this.parseTimeInForce (this.safeString (order, 'time_in_force'));
|
1787
|
+
const stopPrice = this.safeNumber2 (order, 'trigger_price', 'stop_px');
|
1788
|
+
const postOnly = (timeInForce === 'PO');
|
1789
|
+
return this.safeOrder ({
|
1790
|
+
'info': order,
|
1791
|
+
'id': id,
|
1792
|
+
'clientOrderId': clientOrderId,
|
1793
|
+
'timestamp': timestamp,
|
1794
|
+
'datetime': this.iso8601 (timestamp),
|
1795
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
1796
|
+
'symbol': symbol,
|
1797
|
+
'type': type,
|
1798
|
+
'timeInForce': timeInForce,
|
1799
|
+
'postOnly': postOnly,
|
1800
|
+
'side': side,
|
1801
|
+
'price': price,
|
1802
|
+
'stopPrice': stopPrice,
|
1803
|
+
'amount': amount,
|
1804
|
+
'cost': cost,
|
1805
|
+
'average': average,
|
1806
|
+
'filled': filled,
|
1807
|
+
'remaining': remaining,
|
1808
|
+
'status': status,
|
1809
|
+
'fee': fee,
|
1810
|
+
'trades': undefined,
|
1811
|
+
}, market);
|
1812
|
+
}
|
1813
|
+
|
1814
|
+
async fetchOrder (id, symbol = undefined, params = {}) { // TODO
|
1815
|
+
if (symbol === undefined) {
|
1816
|
+
throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument');
|
1817
|
+
}
|
1818
|
+
await this.loadMarkets ();
|
1819
|
+
const market = this.market (symbol);
|
1820
|
+
const request = {
|
1821
|
+
'symbol': market['id'],
|
1822
|
+
// 'order_link_id': 'string', // one of order_id, stop_order_id or order_link_id is required
|
1823
|
+
// regular orders ---------------------------------------------
|
1824
|
+
// 'order_id': id, // one of order_id or order_link_id is required for regular orders
|
1825
|
+
// conditional orders ---------------------------------------------
|
1826
|
+
// 'stop_order_id': id, // one of stop_order_id or order_link_id is required for conditional orders
|
1827
|
+
};
|
1828
|
+
let method = undefined;
|
1829
|
+
if (market['swap']) {
|
1830
|
+
if (market['linear']) {
|
1831
|
+
method = 'privateLinearGetOrderSearch';
|
1832
|
+
} else if (market['inverse']) {
|
1833
|
+
method = 'v2PrivateGetOrder';
|
1834
|
+
}
|
1835
|
+
} else if (market['future']) {
|
1836
|
+
method = 'futuresPrivateGetOrder';
|
1837
|
+
}
|
1838
|
+
const stopOrderId = this.safeString (params, 'stop_order_id');
|
1839
|
+
if (stopOrderId === undefined) {
|
1840
|
+
const orderLinkId = this.safeString (params, 'order_link_id');
|
1841
|
+
if (orderLinkId === undefined) {
|
1842
|
+
request['order_id'] = id;
|
1843
|
+
}
|
1844
|
+
} else {
|
1845
|
+
if (market['swap']) {
|
1846
|
+
if (market['linear']) {
|
1847
|
+
method = 'privateLinearGetStopOrderSearch';
|
1848
|
+
} else if (market['inverse']) {
|
1849
|
+
method = 'v2PrivateGetStopOrder';
|
1850
|
+
}
|
1851
|
+
} else if (market['future']) {
|
1852
|
+
method = 'futuresPrivateGetStopOrder';
|
1853
|
+
}
|
1854
|
+
}
|
1855
|
+
const response = await this[method] (this.extend (request, params));
|
1856
|
+
//
|
1857
|
+
// {
|
1858
|
+
// "ret_code": 0,
|
1859
|
+
// "ret_msg": "OK",
|
1860
|
+
// "ext_code": "",
|
1861
|
+
// "ext_info": "",
|
1862
|
+
// "result": {
|
1863
|
+
// "user_id": 1,
|
1864
|
+
// "symbol": "BTCUSD",
|
1865
|
+
// "side": "Sell",
|
1866
|
+
// "order_type": "Limit",
|
1867
|
+
// "price": "8083",
|
1868
|
+
// "qty": 10,
|
1869
|
+
// "time_in_force": "GoodTillCancel",
|
1870
|
+
// "order_status": "New",
|
1871
|
+
// "ext_fields": { "o_req_num": -308787, "xreq_type": "x_create", "xreq_offset": 4154640 },
|
1872
|
+
// "leaves_qty": 10,
|
1873
|
+
// "leaves_value": "0.00123716",
|
1874
|
+
// "cum_exec_qty": 0,
|
1875
|
+
// "reject_reason": "",
|
1876
|
+
// "order_link_id": "",
|
1877
|
+
// "created_at": "2019-10-21T07:28:19.396246Z",
|
1878
|
+
// "updated_at": "2019-10-21T07:28:19.396246Z",
|
1879
|
+
// "order_id": "efa44157-c355-4a98-b6d6-1d846a936b93"
|
1880
|
+
// },
|
1881
|
+
// "time_now": "1571651135.291930",
|
1882
|
+
// "rate_limit_status": 99, // The remaining number of accesses in one minute
|
1883
|
+
// "rate_limit_reset_ms": 1580885703683,
|
1884
|
+
// "rate_limit": 100
|
1885
|
+
// }
|
1886
|
+
//
|
1887
|
+
// conditional orders
|
1888
|
+
//
|
1889
|
+
// {
|
1890
|
+
// "ret_code": 0,
|
1891
|
+
// "ret_msg": "OK",
|
1892
|
+
// "ext_code": "",
|
1893
|
+
// "ext_info": "",
|
1894
|
+
// "result": {
|
1895
|
+
// "user_id": 1,
|
1896
|
+
// "symbol": "BTCUSD",
|
1897
|
+
// "side": "Buy",
|
1898
|
+
// "order_type": "Limit",
|
1899
|
+
// "price": "8000",
|
1900
|
+
// "qty": 1,
|
1901
|
+
// "time_in_force": "GoodTillCancel",
|
1902
|
+
// "order_status": "Untriggered",
|
1903
|
+
// "ext_fields": {},
|
1904
|
+
// "leaves_qty": 1,
|
1905
|
+
// "leaves_value": "0.00013333",
|
1906
|
+
// "cum_exec_qty": 0,
|
1907
|
+
// "cum_exec_value": null,
|
1908
|
+
// "cum_exec_fee": null,
|
1909
|
+
// "reject_reason": "",
|
1910
|
+
// "order_link_id": "",
|
1911
|
+
// "created_at": "2019-12-27T19:56:24.052194Z",
|
1912
|
+
// "updated_at": "2019-12-27T19:56:24.052194Z",
|
1913
|
+
// "order_id": "378a1bbc-a93a-4e75-87f4-502ea754ba36"
|
1914
|
+
// },
|
1915
|
+
// "time_now": "1577476584.386958",
|
1916
|
+
// "rate_limit_status": 99,
|
1917
|
+
// "rate_limit_reset_ms": 1580885703683,
|
1918
|
+
// "rate_limit": 100
|
1919
|
+
// }
|
1920
|
+
//
|
1921
|
+
const result = this.safeValue (response, 'result');
|
1922
|
+
return this.parseOrder (result, market);
|
1923
|
+
}
|
1924
|
+
|
1925
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
1926
|
+
await this.loadMarkets ();
|
1927
|
+
const market = this.market (symbol);
|
1928
|
+
let qty = this.amountToPrecision (symbol, amount);
|
1929
|
+
if (market['inverse']) {
|
1930
|
+
qty = parseInt (qty);
|
1931
|
+
} else {
|
1932
|
+
qty = parseFloat (qty);
|
1933
|
+
}
|
1934
|
+
const request = {
|
1935
|
+
// orders ---------------------------------------------------------
|
1936
|
+
'side': this.capitalize (side),
|
1937
|
+
'symbol': market['id'],
|
1938
|
+
'order_type': this.capitalize (type),
|
1939
|
+
'qty': qty, // order quantity in USD, integer only
|
1940
|
+
// 'price': parseFloat (this.priceToPrecision (symbol, price)), // required for limit orders
|
1941
|
+
'time_in_force': 'GoodTillCancel', // ImmediateOrCancel, FillOrKill, PostOnly
|
1942
|
+
// 'take_profit': 123.45, // take profit price, only take effect upon opening the position
|
1943
|
+
// 'stop_loss': 123.45, // stop loss price, only take effect upon opening the position
|
1944
|
+
// 'reduce_only': false, // reduce only, required for linear orders
|
1945
|
+
// when creating a closing order, bybit recommends a True value for
|
1946
|
+
// close_on_trigger to avoid failing due to insufficient available margin
|
1947
|
+
// 'close_on_trigger': false, required for linear orders
|
1948
|
+
// 'order_link_id': 'string', // unique client order id, max 36 characters
|
1949
|
+
// conditional orders ---------------------------------------------
|
1950
|
+
// base_price is used to compare with the value of stop_px, to decide
|
1951
|
+
// whether your conditional order will be triggered by crossing trigger
|
1952
|
+
// price from upper side or lower side, mainly used to identify the
|
1953
|
+
// expected direction of the current conditional order
|
1954
|
+
// 'base_price': 123.45, // required for conditional orders
|
1955
|
+
// 'stop_px': 123.45, // trigger price, required for conditional orders
|
1956
|
+
// 'trigger_by': 'LastPrice', // IndexPrice, MarkPrice
|
1957
|
+
};
|
1958
|
+
let priceIsRequired = false;
|
1959
|
+
if (type === 'limit') {
|
1960
|
+
priceIsRequired = true;
|
1961
|
+
}
|
1962
|
+
if (priceIsRequired) {
|
1963
|
+
if (price !== undefined) {
|
1964
|
+
request['price'] = parseFloat (this.priceToPrecision (symbol, price));
|
1965
|
+
} else {
|
1966
|
+
throw new ArgumentsRequired (this.id + ' createOrder() requires a price argument for a ' + type + ' order');
|
1967
|
+
}
|
1968
|
+
}
|
1969
|
+
const clientOrderId = this.safeString2 (params, 'order_link_id', 'clientOrderId');
|
1970
|
+
if (clientOrderId !== undefined) {
|
1971
|
+
request['order_link_id'] = clientOrderId;
|
1972
|
+
params = this.omit (params, [ 'order_link_id', 'clientOrderId' ]);
|
1973
|
+
}
|
1974
|
+
const stopPx = this.safeValue2 (params, 'stop_px', 'stopPrice');
|
1975
|
+
const basePrice = this.safeValue (params, 'base_price');
|
1976
|
+
let method = undefined;
|
1977
|
+
if (market['swap']) {
|
1978
|
+
if (market['linear']) {
|
1979
|
+
method = 'privateLinearPostOrderCreate';
|
1980
|
+
request['reduce_only'] = false;
|
1981
|
+
request['close_on_trigger'] = false;
|
1982
|
+
} else if (market['inverse']) {
|
1983
|
+
method = 'v2PrivatePostOrderCreate';
|
1984
|
+
}
|
1985
|
+
} else if (market['future']) {
|
1986
|
+
method = 'futuresPrivatePostOrderCreate';
|
1987
|
+
}
|
1988
|
+
if (stopPx !== undefined) {
|
1989
|
+
if (basePrice === undefined) {
|
1990
|
+
throw new ArgumentsRequired (this.id + ' createOrder() requires both the stop_px and base_price params for a conditional ' + type + ' order');
|
1991
|
+
} else {
|
1992
|
+
if (market['swap']) {
|
1993
|
+
if (market['linear']) {
|
1994
|
+
method = 'privateLinearPostStopOrderCreate';
|
1995
|
+
} else if (market['inverse']) {
|
1996
|
+
method = 'v2PrivatePostStopOrderCreate';
|
1997
|
+
}
|
1998
|
+
} else if (market['future']) {
|
1999
|
+
method = 'futuresPrivatePostStopOrderCreate';
|
2000
|
+
}
|
2001
|
+
request['stop_px'] = parseFloat (this.priceToPrecision (symbol, stopPx));
|
2002
|
+
request['base_price'] = parseFloat (this.priceToPrecision (symbol, basePrice));
|
2003
|
+
request['trigger_by'] = 'LastPrice';
|
2004
|
+
params = this.omit (params, [ 'stop_px', 'stopPrice', 'base_price', 'trigger_by' ]);
|
2005
|
+
}
|
2006
|
+
} else if (basePrice !== undefined) {
|
2007
|
+
throw new ArgumentsRequired (this.id + ' createOrder() requires both the stop_px and base_price params for a conditional ' + type + ' order');
|
2008
|
+
}
|
2009
|
+
const response = await this[method] (this.extend (request, params));
|
2010
|
+
//
|
2011
|
+
// {
|
2012
|
+
// "ret_code": 0,
|
2013
|
+
// "ret_msg": "OK",
|
2014
|
+
// "ext_code": "",
|
2015
|
+
// "ext_info": "",
|
2016
|
+
// "result": {
|
2017
|
+
// "user_id": 1,
|
2018
|
+
// "order_id": "335fd977-e5a5-4781-b6d0-c772d5bfb95b",
|
2019
|
+
// "symbol": "BTCUSD",
|
2020
|
+
// "side": "Buy",
|
2021
|
+
// "order_type": "Limit",
|
2022
|
+
// "price": 8800,
|
2023
|
+
// "qty": 1,
|
2024
|
+
// "time_in_force": "GoodTillCancel",
|
2025
|
+
// "order_status": "Created",
|
2026
|
+
// "last_exec_time": 0,
|
2027
|
+
// "last_exec_price": 0,
|
2028
|
+
// "leaves_qty": 1,
|
2029
|
+
// "cum_exec_qty": 0,
|
2030
|
+
// "cum_exec_value": 0,
|
2031
|
+
// "cum_exec_fee": 0,
|
2032
|
+
// "reject_reason": "",
|
2033
|
+
// "order_link_id": "",
|
2034
|
+
// "created_at": "2019-11-30T11:03:43.452Z",
|
2035
|
+
// "updated_at": "2019-11-30T11:03:43.455Z"
|
2036
|
+
// },
|
2037
|
+
// "time_now": "1575111823.458705",
|
2038
|
+
// "rate_limit_status": 98,
|
2039
|
+
// "rate_limit_reset_ms": 1580885703683,
|
2040
|
+
// "rate_limit": 100
|
2041
|
+
// }
|
2042
|
+
//
|
2043
|
+
// conditional orders
|
2044
|
+
//
|
2045
|
+
// {
|
2046
|
+
// "ret_code": 0,
|
2047
|
+
// "ret_msg": "ok",
|
2048
|
+
// "ext_code": "",
|
2049
|
+
// "result": {
|
2050
|
+
// "user_id": 1,
|
2051
|
+
// "symbol": "BTCUSD",
|
2052
|
+
// "side": "Buy",
|
2053
|
+
// "order_type": "Limit",
|
2054
|
+
// "price": 8000,
|
2055
|
+
// "qty": 1,
|
2056
|
+
// "time_in_force": "GoodTillCancel",
|
2057
|
+
// "stop_order_type": "Stop",
|
2058
|
+
// "trigger_by": "LastPrice",
|
2059
|
+
// "base_price": 7000,
|
2060
|
+
// "order_status": "Untriggered",
|
2061
|
+
// "ext_fields": {
|
2062
|
+
// "stop_order_type": "Stop",
|
2063
|
+
// "trigger_by": "LastPrice",
|
2064
|
+
// "base_price": 7000,
|
2065
|
+
// "expected_direction": "Rising",
|
2066
|
+
// "trigger_price": 7500,
|
2067
|
+
// "op_from": "api",
|
2068
|
+
// "remark": "127.0.01",
|
2069
|
+
// "o_req_num": 0
|
2070
|
+
// },
|
2071
|
+
// "leaves_qty": 1,
|
2072
|
+
// "leaves_value": 0.00013333,
|
2073
|
+
// "reject_reason": null,
|
2074
|
+
// "cross_seq": -1,
|
2075
|
+
// "created_at": "2019-12-27T12:48:24.000Z",
|
2076
|
+
// "updated_at": "2019-12-27T12:48:24.000Z",
|
2077
|
+
// "stop_px": 7500,
|
2078
|
+
// "stop_order_id": "a85cd1c0-a9a4-49d3-a1bd-bab5ebe946d5"
|
2079
|
+
// },
|
2080
|
+
// "ext_info": null,
|
2081
|
+
// "time_now": "1577450904.327654",
|
2082
|
+
// "rate_limit_status": 99,
|
2083
|
+
// "rate_limit_reset_ms": 1577450904335,
|
2084
|
+
// "rate_limit": "100"
|
2085
|
+
// }
|
2086
|
+
//
|
2087
|
+
const result = this.safeValue (response, 'result');
|
2088
|
+
return this.parseOrder (result, market);
|
2089
|
+
}
|
2090
|
+
|
2091
|
+
async editOrder (id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
2092
|
+
if (symbol === undefined) {
|
2093
|
+
throw new ArgumentsRequired (this.id + ' editOrder() requires an symbol argument');
|
2094
|
+
}
|
2095
|
+
await this.loadMarkets ();
|
2096
|
+
const market = this.market (symbol);
|
2097
|
+
const request = {
|
2098
|
+
// 'order_id': id, // only for non-conditional orders
|
2099
|
+
'symbol': market['id'],
|
2100
|
+
// 'p_r_qty': this.amountToPrecision (symbol, amount), // new order quantity, optional
|
2101
|
+
// 'p_r_price' this.priceToprecision (symbol, price), // new order price, optional
|
2102
|
+
// ----------------------------------------------------------------
|
2103
|
+
// conditional orders
|
2104
|
+
// 'stop_order_id': id, // only for conditional orders
|
2105
|
+
// 'p_r_trigger_price': 123.45, // new trigger price also known as stop_px
|
2106
|
+
};
|
2107
|
+
let method = undefined;
|
2108
|
+
if (market['swap']) {
|
2109
|
+
if (market['linear']) {
|
2110
|
+
method = 'privateLinearPostOrderReplace';
|
2111
|
+
} else if (market['inverse']) {
|
2112
|
+
method = 'v2PrivatePostOrderReplace';
|
2113
|
+
}
|
2114
|
+
} else if (market['future']) {
|
2115
|
+
method = 'futuresPrivatePostOrderReplace';
|
2116
|
+
}
|
2117
|
+
const stopOrderId = this.safeString (params, 'stop_order_id');
|
2118
|
+
if (stopOrderId !== undefined) {
|
2119
|
+
if (market['swap']) {
|
2120
|
+
if (market['linear']) {
|
2121
|
+
method = 'privateLinearPostStopOrderReplace';
|
2122
|
+
} else if (market['inverse']) {
|
2123
|
+
method = 'v2PrivatePostStopOrderReplace';
|
2124
|
+
}
|
2125
|
+
} else if (market['future']) {
|
2126
|
+
method = 'futuresPrivatePostStopOrderReplace';
|
2127
|
+
}
|
2128
|
+
request['stop_order_id'] = stopOrderId;
|
2129
|
+
params = this.omit (params, [ 'stop_order_id' ]);
|
2130
|
+
} else {
|
2131
|
+
request['order_id'] = id;
|
2132
|
+
}
|
2133
|
+
if (amount !== undefined) {
|
2134
|
+
let qty = this.amountToPrecision (symbol, amount);
|
2135
|
+
if (market['inverse']) {
|
2136
|
+
qty = parseInt (qty);
|
2137
|
+
} else {
|
2138
|
+
qty = parseFloat (qty);
|
2139
|
+
}
|
2140
|
+
request['p_r_qty'] = qty;
|
2141
|
+
}
|
2142
|
+
if (price !== undefined) {
|
2143
|
+
request['p_r_price'] = parseFloat (this.priceToPrecision (symbol, price));
|
2144
|
+
}
|
2145
|
+
const response = await this[method] (this.extend (request, params));
|
2146
|
+
//
|
2147
|
+
// {
|
2148
|
+
// "ret_code": 0,
|
2149
|
+
// "ret_msg": "ok",
|
2150
|
+
// "ext_code": "",
|
2151
|
+
// "result": { "order_id": "efa44157-c355-4a98-b6d6-1d846a936b93" },
|
2152
|
+
// "time_now": "1539778407.210858",
|
2153
|
+
// "rate_limit_status": 99, // remaining number of accesses in one minute
|
2154
|
+
// "rate_limit_reset_ms": 1580885703683,
|
2155
|
+
// "rate_limit": 100
|
2156
|
+
// }
|
2157
|
+
//
|
2158
|
+
// conditional orders
|
2159
|
+
//
|
2160
|
+
// {
|
2161
|
+
// "ret_code": 0,
|
2162
|
+
// "ret_msg": "ok",
|
2163
|
+
// "ext_code": "",
|
2164
|
+
// "result": { "stop_order_id": "378a1bbc-a93a-4e75-87f4-502ea754ba36" },
|
2165
|
+
// "ext_info": null,
|
2166
|
+
// "time_now": "1577475760.604942",
|
2167
|
+
// "rate_limit_status": 96,
|
2168
|
+
// "rate_limit_reset_ms": 1577475760612,
|
2169
|
+
// "rate_limit": "100"
|
2170
|
+
// }
|
2171
|
+
//
|
2172
|
+
const result = this.safeValue (response, 'result', {});
|
2173
|
+
return {
|
2174
|
+
'info': response,
|
2175
|
+
'id': this.safeString2 (result, 'order_id', 'stop_order_id'),
|
2176
|
+
'order_id': this.safeString (result, 'order_id'),
|
2177
|
+
'stop_order_id': this.safeString (result, 'stop_order_id'),
|
2178
|
+
};
|
2179
|
+
}
|
2180
|
+
|
2181
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
2182
|
+
if (symbol === undefined) {
|
2183
|
+
throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
|
2184
|
+
}
|
2185
|
+
await this.loadMarkets ();
|
2186
|
+
const market = this.market (symbol);
|
2187
|
+
const request = {
|
2188
|
+
'symbol': market['id'],
|
2189
|
+
// 'order_link_id': 'string', // one of order_id, stop_order_id or order_link_id is required
|
2190
|
+
// regular orders ---------------------------------------------
|
2191
|
+
// 'order_id': id, // one of order_id or order_link_id is required for regular orders
|
2192
|
+
// conditional orders ---------------------------------------------
|
2193
|
+
// 'stop_order_id': id, // one of stop_order_id or order_link_id is required for conditional orders
|
2194
|
+
};
|
2195
|
+
let method = undefined;
|
2196
|
+
if (market['swap']) {
|
2197
|
+
if (market['linear']) {
|
2198
|
+
method = 'privateLinearPostOrderCancel';
|
2199
|
+
} else if (market['inverse']) {
|
2200
|
+
method = 'v2PrivatePostOrderCancel';
|
2201
|
+
}
|
2202
|
+
} else if (market['future']) {
|
2203
|
+
method = 'futuresPrivatePostOrderCancel';
|
2204
|
+
}
|
2205
|
+
const stopOrderId = this.safeString (params, 'stop_order_id');
|
2206
|
+
if (stopOrderId === undefined) {
|
2207
|
+
const orderLinkId = this.safeString (params, 'order_link_id');
|
2208
|
+
if (orderLinkId === undefined) {
|
2209
|
+
request['order_id'] = id;
|
2210
|
+
}
|
2211
|
+
} else {
|
2212
|
+
if (market['swap']) {
|
2213
|
+
if (market['linear']) {
|
2214
|
+
method = 'privateLinearPostStopOrderCancel';
|
2215
|
+
} else if (market['inverse']) {
|
2216
|
+
method = 'v2PrivatePostStopOrderCancel';
|
2217
|
+
}
|
2218
|
+
} else if (market['future']) {
|
2219
|
+
method = 'futuresPrivatePostStopOrderCancel';
|
2220
|
+
}
|
2221
|
+
}
|
2222
|
+
const response = await this[method] (this.extend (request, params));
|
2223
|
+
const result = this.safeValue (response, 'result', {});
|
2224
|
+
return this.parseOrder (result, market);
|
2225
|
+
}
|
2226
|
+
|
2227
|
+
async cancelAllOrders (symbol = undefined, params = {}) {
|
2228
|
+
if (symbol === undefined) {
|
2229
|
+
throw new ArgumentsRequired (this.id + ' cancelAllOrders() requires a symbol argument');
|
2230
|
+
}
|
2231
|
+
await this.loadMarkets ();
|
2232
|
+
const market = this.market (symbol);
|
2233
|
+
const request = {
|
2234
|
+
'symbol': market['id'],
|
2235
|
+
};
|
2236
|
+
const options = this.safeValue (this.options, 'cancelAllOrders', {});
|
2237
|
+
let defaultMethod = undefined;
|
2238
|
+
if (market['swap']) {
|
2239
|
+
if (market['linear']) {
|
2240
|
+
defaultMethod = 'privateLinearPostOrderCancelAll';
|
2241
|
+
} else if (market['inverse']) {
|
2242
|
+
defaultMethod = 'v2PrivatePostOrderCancelAll';
|
2243
|
+
}
|
2244
|
+
} else if (market['future']) {
|
2245
|
+
defaultMethod = 'futuresPrivatePostOrderCancelAll';
|
2246
|
+
}
|
2247
|
+
const stop = this.safeValue (params, 'stop');
|
2248
|
+
if (stop) {
|
2249
|
+
if (market['swap']) {
|
2250
|
+
if (market['linear']) {
|
2251
|
+
defaultMethod = 'privateLinearPostStopOrderCancelAll';
|
2252
|
+
} else if (market['inverse']) {
|
2253
|
+
defaultMethod = 'v2PrivatePostStopOrderCancelAll';
|
2254
|
+
}
|
2255
|
+
} else if (market['future']) {
|
2256
|
+
defaultMethod = 'futuresPrivatePostStopOrderCancelAll';
|
2257
|
+
}
|
2258
|
+
}
|
2259
|
+
const method = this.safeString (options, 'method', defaultMethod);
|
2260
|
+
params = this.omit (params, 'stop');
|
2261
|
+
const response = await this[method] (this.extend (request, params));
|
2262
|
+
const result = this.safeValue (response, 'result', []);
|
2263
|
+
return this.parseOrders (result, market);
|
2264
|
+
}
|
2265
|
+
|
2266
|
+
async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2267
|
+
await this.loadMarkets ();
|
2268
|
+
const request = {
|
2269
|
+
// 'order_id': 'string'
|
2270
|
+
// 'order_link_id': 'string', // unique client order id, max 36 characters
|
2271
|
+
// 'symbol': market['id'], // default BTCUSD
|
2272
|
+
// 'order': 'desc', // asc
|
2273
|
+
// 'page': 1,
|
2274
|
+
// 'limit': 20, // max 50
|
2275
|
+
// 'order_status': 'Created,New'
|
2276
|
+
// conditional orders ---------------------------------------------
|
2277
|
+
// 'stop_order_id': 'string',
|
2278
|
+
// 'stop_order_status': 'Untriggered',
|
2279
|
+
};
|
2280
|
+
let market = undefined;
|
2281
|
+
if (symbol !== undefined) {
|
2282
|
+
market = this.market (symbol);
|
2283
|
+
request['symbol'] = market['id'];
|
2284
|
+
}
|
2285
|
+
if (limit !== undefined) {
|
2286
|
+
request['limit'] = limit;
|
2287
|
+
}
|
2288
|
+
const options = this.safeValue (this.options, 'fetchOrders', {});
|
2289
|
+
const defaultType = this.safeString (this.options, 'defaultType', 'linear');
|
2290
|
+
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
2291
|
+
const marketType = this.safeString (marketTypes, symbol, defaultType);
|
2292
|
+
let defaultMethod = undefined;
|
2293
|
+
const marketDefined = (market !== undefined);
|
2294
|
+
const linear = (marketDefined && market['linear']) || (marketType === 'linear');
|
2295
|
+
const inverse = (marketDefined && market['swap'] && market['inverse']) || (marketType === 'inverse');
|
2296
|
+
const future = (marketDefined && market['future']) || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
|
2297
|
+
if (linear) {
|
2298
|
+
defaultMethod = 'privateLinearGetOrderList';
|
2299
|
+
} else if (inverse) {
|
2300
|
+
defaultMethod = 'v2PrivateGetOrderList';
|
2301
|
+
} else if (future) {
|
2302
|
+
defaultMethod = 'futuresPrivateGetOrderList';
|
2303
|
+
}
|
2304
|
+
let query = params;
|
2305
|
+
if (('stop_order_id' in params) || ('stop_order_status' in params)) {
|
2306
|
+
let stopOrderStatus = this.safeValue (params, 'stop_order_status');
|
2307
|
+
if (stopOrderStatus !== undefined) {
|
2308
|
+
if (Array.isArray (stopOrderStatus)) {
|
2309
|
+
stopOrderStatus = stopOrderStatus.join (',');
|
2310
|
+
}
|
2311
|
+
request['stop_order_status'] = stopOrderStatus;
|
2312
|
+
query = this.omit (params, 'stop_order_status');
|
2313
|
+
}
|
2314
|
+
if (linear) {
|
2315
|
+
defaultMethod = 'privateLinearGetStopOrderList';
|
2316
|
+
} else if (inverse) {
|
2317
|
+
defaultMethod = 'v2PrivateGetStopOrderList';
|
2318
|
+
} else if (future) {
|
2319
|
+
defaultMethod = 'futuresPrivateGetStopOrderList';
|
2320
|
+
}
|
2321
|
+
}
|
2322
|
+
const method = this.safeString (options, 'method', defaultMethod);
|
2323
|
+
const response = await this[method] (this.extend (request, query));
|
2324
|
+
//
|
2325
|
+
// {
|
2326
|
+
// "ret_code": 0,
|
2327
|
+
// "ret_msg": "ok",
|
2328
|
+
// "ext_code": "",
|
2329
|
+
// "result": {
|
2330
|
+
// "current_page": 1,
|
2331
|
+
// "last_page": 6,
|
2332
|
+
// "data": [
|
2333
|
+
// {
|
2334
|
+
// "user_id": 1,
|
2335
|
+
// "symbol": "BTCUSD",
|
2336
|
+
// "side": "Sell",
|
2337
|
+
// "order_type": "Market",
|
2338
|
+
// "price": 7074,
|
2339
|
+
// "qty": 2,
|
2340
|
+
// "time_in_force": "ImmediateOrCancel",
|
2341
|
+
// "order_status": "Filled",
|
2342
|
+
// "ext_fields": {
|
2343
|
+
// "close_on_trigger": true,
|
2344
|
+
// "orig_order_type": "BLimit",
|
2345
|
+
// "prior_x_req_price": 5898.5,
|
2346
|
+
// "op_from": "pc",
|
2347
|
+
// "remark": "127.0.0.1",
|
2348
|
+
// "o_req_num": -34799032763,
|
2349
|
+
// "xreq_type": "x_create"
|
2350
|
+
// },
|
2351
|
+
// "last_exec_time": "1577448481.696421",
|
2352
|
+
// "last_exec_price": 7070.5,
|
2353
|
+
// "leaves_qty": 0,
|
2354
|
+
// "leaves_value": 0,
|
2355
|
+
// "cum_exec_qty": 2,
|
2356
|
+
// "cum_exec_value": 0.00028283,
|
2357
|
+
// "cum_exec_fee": 0.00002,
|
2358
|
+
// "reject_reason": "NoError",
|
2359
|
+
// "order_link_id": "",
|
2360
|
+
// "created_at": "2019-12-27T12:08:01.000Z",
|
2361
|
+
// "updated_at": "2019-12-27T12:08:01.000Z",
|
2362
|
+
// "order_id": "f185806b-b801-40ff-adec-52289370ed62"
|
2363
|
+
// }
|
2364
|
+
// ]
|
2365
|
+
// },
|
2366
|
+
// "ext_info": null,
|
2367
|
+
// "time_now": "1577448922.437871",
|
2368
|
+
// "rate_limit_status": 98,
|
2369
|
+
// "rate_limit_reset_ms": 1580885703683,
|
2370
|
+
// "rate_limit": 100
|
2371
|
+
// }
|
2372
|
+
//
|
2373
|
+
// linear swaps
|
2374
|
+
//
|
2375
|
+
// {
|
2376
|
+
// "ret_code":0,
|
2377
|
+
// "ret_msg":"OK",
|
2378
|
+
// "ext_code":"",
|
2379
|
+
// "ext_info":"",
|
2380
|
+
// "result":{
|
2381
|
+
// "current_page":1,
|
2382
|
+
// "data":[
|
2383
|
+
// {
|
2384
|
+
// "order_id":"7917bd70-e7c3-4af5-8147-3285cd99c509",
|
2385
|
+
// "user_id":22919890,
|
2386
|
+
// "symbol":"GMTUSDT",
|
2387
|
+
// "side":"Buy",
|
2388
|
+
// "order_type":"Limit",
|
2389
|
+
// "price":2.9262,
|
2390
|
+
// "qty":50,
|
2391
|
+
// "time_in_force":"GoodTillCancel",
|
2392
|
+
// "order_status":"Filled",
|
2393
|
+
// "last_exec_price":2.9219,
|
2394
|
+
// "cum_exec_qty":50,
|
2395
|
+
// "cum_exec_value":146.095,
|
2396
|
+
// "cum_exec_fee":0.087657,
|
2397
|
+
// "reduce_only":false,
|
2398
|
+
// "close_on_trigger":false,
|
2399
|
+
// "order_link_id":"",
|
2400
|
+
// "created_time":"2022-04-18T17:09:54Z",
|
2401
|
+
// "updated_time":"2022-04-18T17:09:54Z",
|
2402
|
+
// "take_profit":0,
|
2403
|
+
// "stop_loss":0,
|
2404
|
+
// "tp_trigger_by":"UNKNOWN",
|
2405
|
+
// "sl_trigger_by":"UNKNOWN"
|
2406
|
+
// }
|
2407
|
+
// ]
|
2408
|
+
// },
|
2409
|
+
// "time_now":"1650970113.283952",
|
2410
|
+
// "rate_limit_status":599,
|
2411
|
+
// "rate_limit_reset_ms":1650970113275,
|
2412
|
+
// "rate_limit":600
|
2413
|
+
// }
|
2414
|
+
//
|
2415
|
+
// conditional orders
|
2416
|
+
//
|
2417
|
+
// {
|
2418
|
+
// "ret_code": 0,
|
2419
|
+
// "ret_msg": "ok",
|
2420
|
+
// "ext_code": "",
|
2421
|
+
// "result": {
|
2422
|
+
// "current_page": 1,
|
2423
|
+
// "last_page": 1,
|
2424
|
+
// "data": [
|
2425
|
+
// {
|
2426
|
+
// "user_id": 1,
|
2427
|
+
// "stop_order_status": "Untriggered",
|
2428
|
+
// "symbol": "BTCUSD",
|
2429
|
+
// "side": "Buy",
|
2430
|
+
// "order_type": "Limit",
|
2431
|
+
// "price": 8000,
|
2432
|
+
// "qty": 1,
|
2433
|
+
// "time_in_force": "GoodTillCancel",
|
2434
|
+
// "stop_order_type": "Stop",
|
2435
|
+
// "trigger_by": "LastPrice",
|
2436
|
+
// "base_price": 7000,
|
2437
|
+
// "order_link_id": "",
|
2438
|
+
// "created_at": "2019-12-27T12:48:24.000Z",
|
2439
|
+
// "updated_at": "2019-12-27T12:48:24.000Z",
|
2440
|
+
// "stop_px": 7500,
|
2441
|
+
// "stop_order_id": "a85cd1c0-a9a4-49d3-a1bd-bab5ebe946d5"
|
2442
|
+
// },
|
2443
|
+
// ]
|
2444
|
+
// },
|
2445
|
+
// "ext_info": null,
|
2446
|
+
// "time_now": "1577451658.755468",
|
2447
|
+
// "rate_limit_status": 599,
|
2448
|
+
// "rate_limit_reset_ms": 1577451658762,
|
2449
|
+
// "rate_limit": 600
|
2450
|
+
// }
|
2451
|
+
//
|
2452
|
+
const result = this.safeValue (response, 'result', {});
|
2453
|
+
const data = this.safeValue (result, 'data', []);
|
2454
|
+
return this.parseOrders (data, market, since, limit);
|
2455
|
+
}
|
2456
|
+
|
2457
|
+
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2458
|
+
const defaultStatuses = [
|
2459
|
+
'Rejected',
|
2460
|
+
'Filled',
|
2461
|
+
'Cancelled',
|
2462
|
+
// conditional orders
|
2463
|
+
// 'Active',
|
2464
|
+
// 'Triggered',
|
2465
|
+
// 'Cancelled',
|
2466
|
+
// 'Rejected',
|
2467
|
+
// 'Deactivated',
|
2468
|
+
];
|
2469
|
+
const options = this.safeValue (this.options, 'fetchClosedOrders', {});
|
2470
|
+
let status = this.safeValue (options, 'order_status', defaultStatuses);
|
2471
|
+
if (Array.isArray (status)) {
|
2472
|
+
status = status.join (',');
|
2473
|
+
}
|
2474
|
+
const request = {};
|
2475
|
+
const stopOrderStatus = this.safeValue (params, 'stop_order_status');
|
2476
|
+
if (stopOrderStatus === undefined) {
|
2477
|
+
request['order_status'] = status;
|
2478
|
+
} else {
|
2479
|
+
request['stop_order_status'] = stopOrderStatus;
|
2480
|
+
}
|
2481
|
+
return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
|
2482
|
+
}
|
2483
|
+
|
2484
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2485
|
+
const defaultStatuses = [
|
2486
|
+
'Created',
|
2487
|
+
'New',
|
2488
|
+
'PartiallyFilled',
|
2489
|
+
'PendingCancel',
|
2490
|
+
// conditional orders
|
2491
|
+
// 'Untriggered',
|
2492
|
+
];
|
2493
|
+
const options = this.safeValue (this.options, 'fetchOpenOrders', {});
|
2494
|
+
let status = this.safeValue (options, 'order_status', defaultStatuses);
|
2495
|
+
if (Array.isArray (status)) {
|
2496
|
+
status = status.join (',');
|
2497
|
+
}
|
2498
|
+
const request = {};
|
2499
|
+
const stopOrderStatus = this.safeValue (params, 'stop_order_status');
|
2500
|
+
if (stopOrderStatus === undefined) {
|
2501
|
+
request['order_status'] = status;
|
2502
|
+
} else {
|
2503
|
+
request['stop_order_status'] = stopOrderStatus;
|
2504
|
+
}
|
2505
|
+
return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
|
2506
|
+
}
|
2507
|
+
|
2508
|
+
async fetchOrderTrades (id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2509
|
+
const request = {
|
2510
|
+
'order_id': id,
|
2511
|
+
};
|
2512
|
+
return await this.fetchMyTrades (symbol, since, limit, this.extend (request, params));
|
2513
|
+
}
|
2514
|
+
|
2515
|
+
async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2516
|
+
if (symbol === undefined) {
|
2517
|
+
throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a symbol argument');
|
2518
|
+
}
|
2519
|
+
await this.loadMarkets ();
|
2520
|
+
const request = {
|
2521
|
+
// 'order_id': 'f185806b-b801-40ff-adec-52289370ed62', // if not provided will return user's trading records
|
2522
|
+
// 'symbol': market['id'],
|
2523
|
+
// 'start_time': parseInt (since / 1000),
|
2524
|
+
// 'page': 1,
|
2525
|
+
// 'limit' 20, // max 50
|
2526
|
+
};
|
2527
|
+
let market = undefined;
|
2528
|
+
const orderId = this.safeString (params, 'order_id');
|
2529
|
+
if (orderId !== undefined) {
|
2530
|
+
request['order_id'] = orderId;
|
2531
|
+
params = this.omit (params, 'order_id');
|
2532
|
+
}
|
2533
|
+
market = this.market (symbol);
|
2534
|
+
request['symbol'] = market['id'];
|
2535
|
+
if (since !== undefined) {
|
2536
|
+
request['start_time'] = since;
|
2537
|
+
}
|
2538
|
+
if (limit !== undefined) {
|
2539
|
+
request['limit'] = limit; // default 20, max 50
|
2540
|
+
}
|
2541
|
+
const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchMyTrades', market, params);
|
2542
|
+
const marketDefined = (market !== undefined);
|
2543
|
+
const linear = (marketDefined && market['linear']) || (marketType === 'linear');
|
2544
|
+
const inverse = (marketDefined && market['swap'] && market['inverse']) || (marketType === 'inverse');
|
2545
|
+
const future = (marketDefined && market['future']) || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
|
2546
|
+
let method = undefined;
|
2547
|
+
if (linear) {
|
2548
|
+
method = 'privateLinearGetTradeExecutionList';
|
2549
|
+
} else if (inverse) {
|
2550
|
+
method = 'v2PrivateGetExecutionList';
|
2551
|
+
} else if (future) {
|
2552
|
+
method = 'futuresPrivateGetExecutionList';
|
2553
|
+
}
|
2554
|
+
const response = await this[method] (this.extend (request, query));
|
2555
|
+
//
|
2556
|
+
// inverse
|
2557
|
+
//
|
2558
|
+
// {
|
2559
|
+
// "ret_code": 0,
|
2560
|
+
// "ret_msg": "OK",
|
2561
|
+
// "ext_code": "",
|
2562
|
+
// "ext_info": "",
|
2563
|
+
// "result": {
|
2564
|
+
// "order_id": "Abandoned!!", // Abandoned!!
|
2565
|
+
// "trade_list": [
|
2566
|
+
// {
|
2567
|
+
// "closed_size": 0,
|
2568
|
+
// "cross_seq": 277136382,
|
2569
|
+
// "exec_fee": "0.0000001",
|
2570
|
+
// "exec_id": "256e5ef8-abfe-5772-971b-f944e15e0d68",
|
2571
|
+
// "exec_price": "8178.5",
|
2572
|
+
// "exec_qty": 1,
|
2573
|
+
// "exec_time": "1571676941.70682",
|
2574
|
+
// "exec_type": "Trade", //Exec Type Enum
|
2575
|
+
// "exec_value": "0.00012227",
|
2576
|
+
// "fee_rate": "0.00075",
|
2577
|
+
// "last_liquidity_ind": "RemovedLiquidity", //Liquidity Enum
|
2578
|
+
// "leaves_qty": 0,
|
2579
|
+
// "nth_fill": 2,
|
2580
|
+
// "order_id": "7ad50cb1-9ad0-4f74-804b-d82a516e1029",
|
2581
|
+
// "order_link_id": "",
|
2582
|
+
// "order_price": "8178",
|
2583
|
+
// "order_qty": 1,
|
2584
|
+
// "order_type": "Market", //Order Type Enum
|
2585
|
+
// "side": "Buy", //Side Enum
|
2586
|
+
// "symbol": "BTCUSD", //Symbol Enum
|
2587
|
+
// "user_id": 1
|
2588
|
+
// }
|
2589
|
+
// ]
|
2590
|
+
// },
|
2591
|
+
// "time_now": "1577483699.281488",
|
2592
|
+
// "rate_limit_status": 118,
|
2593
|
+
// "rate_limit_reset_ms": 1577483699244737,
|
2594
|
+
// "rate_limit": 120
|
2595
|
+
// }
|
2596
|
+
//
|
2597
|
+
// linear
|
2598
|
+
//
|
2599
|
+
// {
|
2600
|
+
// "ret_code":0,
|
2601
|
+
// "ret_msg":"OK",
|
2602
|
+
// "ext_code":"",
|
2603
|
+
// "ext_info":"",
|
2604
|
+
// "result":{
|
2605
|
+
// "current_page":1,
|
2606
|
+
// "data":[
|
2607
|
+
// {
|
2608
|
+
// "order_id":"b59418ec-14d4-4ef9-b9f4-721d5d576974",
|
2609
|
+
// "order_link_id":"",
|
2610
|
+
// "side":"Sell",
|
2611
|
+
// "symbol":"BTCUSDT",
|
2612
|
+
// "exec_id":"0327284d-faec-5191-bd89-acc5b4fafda9",
|
2613
|
+
// "price":0.5,
|
2614
|
+
// "order_price":0.5,
|
2615
|
+
// "order_qty":0.01,
|
2616
|
+
// "order_type":"Market",
|
2617
|
+
// "fee_rate":0.00075,
|
2618
|
+
// "exec_price":9709.5,
|
2619
|
+
// "exec_type":"Trade",
|
2620
|
+
// "exec_qty":0.01,
|
2621
|
+
// "exec_fee":0.07282125,
|
2622
|
+
// "exec_value":97.095,
|
2623
|
+
// "leaves_qty":0,
|
2624
|
+
// "closed_size":0.01,
|
2625
|
+
// "last_liquidity_ind":"RemovedLiquidity",
|
2626
|
+
// "trade_time":1591648052,
|
2627
|
+
// "trade_time_ms":1591648052861
|
2628
|
+
// }
|
2629
|
+
// ]
|
2630
|
+
// },
|
2631
|
+
// "time_now":"1591736501.979264",
|
2632
|
+
// "rate_limit_status":119,
|
2633
|
+
// "rate_limit_reset_ms":1591736501974,
|
2634
|
+
// "rate_limit":120
|
2635
|
+
// }
|
2636
|
+
//
|
2637
|
+
const result = this.safeValue (response, 'result', {});
|
2638
|
+
const trades = this.safeValue2 (result, 'trade_list', 'data', []);
|
2639
|
+
return this.parseTrades (trades, market, since, limit);
|
2640
|
+
}
|
2641
|
+
|
2642
|
+
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2643
|
+
await this.loadMarkets ();
|
2644
|
+
const request = {
|
2645
|
+
// 'coin': currency['id'],
|
2646
|
+
// 'currency': currency['id'], // alias
|
2647
|
+
// 'start_date': this.iso8601 (since),
|
2648
|
+
// 'end_date': this.iso8601 (till),
|
2649
|
+
'wallet_fund_type': 'Deposit', // Deposit, Withdraw, RealisedPNL, Commission, Refund, Prize, ExchangeOrderWithdraw, ExchangeOrderDeposit
|
2650
|
+
// 'page': 1,
|
2651
|
+
// 'limit': 20, // max 50
|
2652
|
+
};
|
2653
|
+
let currency = undefined;
|
2654
|
+
if (code !== undefined) {
|
2655
|
+
currency = this.currency (code);
|
2656
|
+
request['coin'] = currency['id'];
|
2657
|
+
}
|
2658
|
+
if (since !== undefined) {
|
2659
|
+
request['start_date'] = this.yyyymmdd (since);
|
2660
|
+
}
|
2661
|
+
if (limit !== undefined) {
|
2662
|
+
request['limit'] = limit;
|
2663
|
+
}
|
2664
|
+
const response = await this.v2PrivateGetWalletFundRecords (this.extend (request, params));
|
2665
|
+
//
|
2666
|
+
// {
|
2667
|
+
// "ret_code": 0,
|
2668
|
+
// "ret_msg": "ok",
|
2669
|
+
// "ext_code": "",
|
2670
|
+
// "result": {
|
2671
|
+
// "data": [
|
2672
|
+
// {
|
2673
|
+
// "id": 234467,
|
2674
|
+
// "user_id": 1,
|
2675
|
+
// "coin": "BTC",
|
2676
|
+
// "wallet_id": 27913,
|
2677
|
+
// "type": "Realized P&L",
|
2678
|
+
// "amount": "-0.00000006",
|
2679
|
+
// "tx_id": "",
|
2680
|
+
// "address": "BTCUSD",
|
2681
|
+
// "wallet_balance": "0.03000330",
|
2682
|
+
// "exec_time": "2019-12-09T00:00:25.000Z",
|
2683
|
+
// "cross_seq": 0
|
2684
|
+
// }
|
2685
|
+
// ]
|
2686
|
+
// },
|
2687
|
+
// "ext_info": null,
|
2688
|
+
// "time_now": "1577481867.115552",
|
2689
|
+
// "rate_limit_status": 119,
|
2690
|
+
// "rate_limit_reset_ms": 1577481867122,
|
2691
|
+
// "rate_limit": 120
|
2692
|
+
// }
|
2693
|
+
//
|
2694
|
+
const result = this.safeValue (response, 'result', {});
|
2695
|
+
const data = this.safeValue (result, 'data', []);
|
2696
|
+
return this.parseTransactions (data, currency, since, limit, { 'type': 'deposit' });
|
2697
|
+
}
|
2698
|
+
|
2699
|
+
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2700
|
+
await this.loadMarkets ();
|
2701
|
+
const request = {
|
2702
|
+
// 'coin': currency['id'],
|
2703
|
+
// 'start_date': this.iso8601 (since),
|
2704
|
+
// 'end_date': this.iso8601 (till),
|
2705
|
+
// 'status': 'Pending', // ToBeConfirmed, UnderReview, Pending, Success, CancelByUser, Reject, Expire
|
2706
|
+
// 'page': 1,
|
2707
|
+
// 'limit': 20, // max 50
|
2708
|
+
};
|
2709
|
+
let currency = undefined;
|
2710
|
+
if (code !== undefined) {
|
2711
|
+
currency = this.currency (code);
|
2712
|
+
request['coin'] = currency['id'];
|
2713
|
+
}
|
2714
|
+
if (since !== undefined) {
|
2715
|
+
request['start_date'] = this.yyyymmdd (since);
|
2716
|
+
}
|
2717
|
+
if (limit !== undefined) {
|
2718
|
+
request['limit'] = limit;
|
2719
|
+
}
|
2720
|
+
const response = await this.v2PrivateGetWalletWithdrawList (this.extend (request, params));
|
2721
|
+
//
|
2722
|
+
// {
|
2723
|
+
// "ret_code": 0,
|
2724
|
+
// "ret_msg": "ok",
|
2725
|
+
// "ext_code": "",
|
2726
|
+
// "result": {
|
2727
|
+
// "data": [
|
2728
|
+
// {
|
2729
|
+
// "id": 137,
|
2730
|
+
// "user_id": 1,
|
2731
|
+
// "coin": "XRP", // Coin Enum
|
2732
|
+
// "status": "Pending", // Withdraw Status Enum
|
2733
|
+
// "amount": "20.00000000",
|
2734
|
+
// "fee": "0.25000000",
|
2735
|
+
// "address": "rH7H595XYEVTEHU2FySYsWnmfACBnZS9zM",
|
2736
|
+
// "tx_id": "",
|
2737
|
+
// "submited_at": "2019-06-11T02:20:24.000Z",
|
2738
|
+
// "updated_at": "2019-06-11T02:20:24.000Z"
|
2739
|
+
// },
|
2740
|
+
// ],
|
2741
|
+
// "current_page": 1,
|
2742
|
+
// "last_page": 1
|
2743
|
+
// },
|
2744
|
+
// "ext_info": null,
|
2745
|
+
// "time_now": "1577482295.125488",
|
2746
|
+
// "rate_limit_status": 119,
|
2747
|
+
// "rate_limit_reset_ms": 1577482295132,
|
2748
|
+
// "rate_limit": 120
|
2749
|
+
// }
|
2750
|
+
//
|
2751
|
+
const result = this.safeValue (response, 'result', {});
|
2752
|
+
const data = this.safeValue (result, 'data', []);
|
2753
|
+
return this.parseTransactions (data, currency, since, limit, { 'type': 'withdrawal' });
|
2754
|
+
}
|
2755
|
+
|
2756
|
+
parseTransactionStatus (status) {
|
2757
|
+
const statuses = {
|
2758
|
+
'ToBeConfirmed': 'pending',
|
2759
|
+
'UnderReview': 'pending',
|
2760
|
+
'Pending': 'pending',
|
2761
|
+
'Success': 'ok',
|
2762
|
+
'CancelByUser': 'canceled',
|
2763
|
+
'Reject': 'rejected',
|
2764
|
+
'Expire': 'expired',
|
2765
|
+
};
|
2766
|
+
return this.safeString (statuses, status, status);
|
2767
|
+
}
|
2768
|
+
|
2769
|
+
parseTransaction (transaction, currency = undefined) {
|
2770
|
+
//
|
2771
|
+
// fetchWithdrawals
|
2772
|
+
//
|
2773
|
+
// {
|
2774
|
+
// "id": 137,
|
2775
|
+
// "user_id": 1,
|
2776
|
+
// "coin": "XRP", // Coin Enum
|
2777
|
+
// "status": "Pending", // Withdraw Status Enum
|
2778
|
+
// "amount": "20.00000000",
|
2779
|
+
// "fee": "0.25000000",
|
2780
|
+
// "address": "rH7H595XYEVTEHU2FySYsWnmfACBnZS9zM",
|
2781
|
+
// "tx_id": "",
|
2782
|
+
// "submited_at": "2019-06-11T02:20:24.000Z",
|
2783
|
+
// "updated_at": "2019-06-11T02:20:24.000Z"
|
2784
|
+
// }
|
2785
|
+
//
|
2786
|
+
// fetchDeposits ledger entries
|
2787
|
+
//
|
2788
|
+
// {
|
2789
|
+
// "id": 234467,
|
2790
|
+
// "user_id": 1,
|
2791
|
+
// "coin": "BTC",
|
2792
|
+
// "wallet_id": 27913,
|
2793
|
+
// "type": "Realized P&L",
|
2794
|
+
// "amount": "-0.00000006",
|
2795
|
+
// "tx_id": "",
|
2796
|
+
// "address": "BTCUSD",
|
2797
|
+
// "wallet_balance": "0.03000330",
|
2798
|
+
// "exec_time": "2019-12-09T00:00:25.000Z",
|
2799
|
+
// "cross_seq": 0
|
2800
|
+
// }
|
2801
|
+
//
|
2802
|
+
const currencyId = this.safeString (transaction, 'coin');
|
2803
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
2804
|
+
const timestamp = this.parse8601 (this.safeString2 (transaction, 'submited_at', 'exec_time'));
|
2805
|
+
const updated = this.parse8601 (this.safeString (transaction, 'updated_at'));
|
2806
|
+
const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
|
2807
|
+
const address = this.safeString (transaction, 'address');
|
2808
|
+
const feeCost = this.safeNumber (transaction, 'fee');
|
2809
|
+
const type = this.safeStringLower (transaction, 'type');
|
2810
|
+
let fee = undefined;
|
2811
|
+
if (feeCost !== undefined) {
|
2812
|
+
fee = {
|
2813
|
+
'cost': feeCost,
|
2814
|
+
'currency': code,
|
2815
|
+
};
|
2816
|
+
}
|
2817
|
+
return {
|
2818
|
+
'info': transaction,
|
2819
|
+
'id': this.safeString (transaction, 'id'),
|
2820
|
+
'txid': this.safeString (transaction, 'tx_id'),
|
2821
|
+
'timestamp': timestamp,
|
2822
|
+
'datetime': this.iso8601 (timestamp),
|
2823
|
+
'network': undefined,
|
2824
|
+
'address': address,
|
2825
|
+
'addressTo': undefined,
|
2826
|
+
'addressFrom': undefined,
|
2827
|
+
'tag': undefined,
|
2828
|
+
'tagTo': undefined,
|
2829
|
+
'tagFrom': undefined,
|
2830
|
+
'type': type,
|
2831
|
+
'amount': this.safeNumber (transaction, 'amount'),
|
2832
|
+
'currency': code,
|
2833
|
+
'status': status,
|
2834
|
+
'updated': updated,
|
2835
|
+
'fee': fee,
|
2836
|
+
};
|
2837
|
+
}
|
2838
|
+
|
2839
|
+
async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
|
2840
|
+
await this.loadMarkets ();
|
2841
|
+
const request = {
|
2842
|
+
// 'coin': currency['id'],
|
2843
|
+
// 'currency': currency['id'], // alias
|
2844
|
+
// 'start_date': this.iso8601 (since),
|
2845
|
+
// 'end_date': this.iso8601 (till),
|
2846
|
+
// 'wallet_fund_type': 'Deposit', // Withdraw, RealisedPNL, Commission, Refund, Prize, ExchangeOrderWithdraw, ExchangeOrderDeposit
|
2847
|
+
// 'page': 1,
|
2848
|
+
// 'limit': 20, // max 50
|
2849
|
+
};
|
2850
|
+
let currency = undefined;
|
2851
|
+
if (code !== undefined) {
|
2852
|
+
currency = this.currency (code);
|
2853
|
+
request['coin'] = currency['id'];
|
2854
|
+
}
|
2855
|
+
if (since !== undefined) {
|
2856
|
+
request['start_date'] = this.yyyymmdd (since);
|
2857
|
+
}
|
2858
|
+
if (limit !== undefined) {
|
2859
|
+
request['limit'] = limit;
|
2860
|
+
}
|
2861
|
+
const response = await this.v2PrivateGetWalletFundRecords (this.extend (request, params));
|
2862
|
+
//
|
2863
|
+
// {
|
2864
|
+
// "ret_code": 0,
|
2865
|
+
// "ret_msg": "ok",
|
2866
|
+
// "ext_code": "",
|
2867
|
+
// "result": {
|
2868
|
+
// "data": [
|
2869
|
+
// {
|
2870
|
+
// "id": 234467,
|
2871
|
+
// "user_id": 1,
|
2872
|
+
// "coin": "BTC",
|
2873
|
+
// "wallet_id": 27913,
|
2874
|
+
// "type": "Realized P&L",
|
2875
|
+
// "amount": "-0.00000006",
|
2876
|
+
// "tx_id": "",
|
2877
|
+
// "address": "BTCUSD",
|
2878
|
+
// "wallet_balance": "0.03000330",
|
2879
|
+
// "exec_time": "2019-12-09T00:00:25.000Z",
|
2880
|
+
// "cross_seq": 0
|
2881
|
+
// }
|
2882
|
+
// ]
|
2883
|
+
// },
|
2884
|
+
// "ext_info": null,
|
2885
|
+
// "time_now": "1577481867.115552",
|
2886
|
+
// "rate_limit_status": 119,
|
2887
|
+
// "rate_limit_reset_ms": 1577481867122,
|
2888
|
+
// "rate_limit": 120
|
2889
|
+
// }
|
2890
|
+
//
|
2891
|
+
const result = this.safeValue (response, 'result', {});
|
2892
|
+
const data = this.safeValue (result, 'data', []);
|
2893
|
+
return this.parseLedger (data, currency, since, limit);
|
2894
|
+
}
|
2895
|
+
|
2896
|
+
parseLedgerEntry (item, currency = undefined) {
|
2897
|
+
//
|
2898
|
+
// {
|
2899
|
+
// "id": 234467,
|
2900
|
+
// "user_id": 1,
|
2901
|
+
// "coin": "BTC",
|
2902
|
+
// "wallet_id": 27913,
|
2903
|
+
// "type": "Realized P&L",
|
2904
|
+
// "amount": "-0.00000006",
|
2905
|
+
// "tx_id": "",
|
2906
|
+
// "address": "BTCUSD",
|
2907
|
+
// "wallet_balance": "0.03000330",
|
2908
|
+
// "exec_time": "2019-12-09T00:00:25.000Z",
|
2909
|
+
// "cross_seq": 0
|
2910
|
+
// }
|
2911
|
+
//
|
2912
|
+
const currencyId = this.safeString (item, 'coin');
|
2913
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
2914
|
+
const amount = this.safeNumber (item, 'amount');
|
2915
|
+
const after = this.safeNumber (item, 'wallet_balance');
|
2916
|
+
const direction = (amount < 0) ? 'out' : 'in';
|
2917
|
+
let before = undefined;
|
2918
|
+
if (after !== undefined && amount !== undefined) {
|
2919
|
+
const difference = (direction === 'out') ? amount : -amount;
|
2920
|
+
before = this.sum (after, difference);
|
2921
|
+
}
|
2922
|
+
const timestamp = this.parse8601 (this.safeString (item, 'exec_time'));
|
2923
|
+
const type = this.parseLedgerEntryType (this.safeString (item, 'type'));
|
2924
|
+
const id = this.safeString (item, 'id');
|
2925
|
+
const referenceId = this.safeString (item, 'tx_id');
|
2926
|
+
return {
|
2927
|
+
'id': id,
|
2928
|
+
'currency': code,
|
2929
|
+
'account': this.safeString (item, 'wallet_id'),
|
2930
|
+
'referenceAccount': undefined,
|
2931
|
+
'referenceId': referenceId,
|
2932
|
+
'status': undefined,
|
2933
|
+
'amount': amount,
|
2934
|
+
'before': before,
|
2935
|
+
'after': after,
|
2936
|
+
'fee': undefined,
|
2937
|
+
'direction': direction,
|
2938
|
+
'timestamp': timestamp,
|
2939
|
+
'datetime': this.iso8601 (timestamp),
|
2940
|
+
'type': type,
|
2941
|
+
'info': item,
|
2942
|
+
};
|
2943
|
+
}
|
2944
|
+
|
2945
|
+
parseLedgerEntryType (type) {
|
2946
|
+
const types = {
|
2947
|
+
'Deposit': 'transaction',
|
2948
|
+
'Withdraw': 'transaction',
|
2949
|
+
'RealisedPNL': 'trade',
|
2950
|
+
'Commission': 'fee',
|
2951
|
+
'Refund': 'cashback',
|
2952
|
+
'Prize': 'prize', // ?
|
2953
|
+
'ExchangeOrderWithdraw': 'transaction',
|
2954
|
+
'ExchangeOrderDeposit': 'transaction',
|
2955
|
+
};
|
2956
|
+
return this.safeString (types, type, type);
|
2957
|
+
}
|
2958
|
+
|
2959
|
+
async fetchPositions (symbols = undefined, params = {}) {
|
2960
|
+
await this.loadMarkets ();
|
2961
|
+
const request = {};
|
2962
|
+
if (Array.isArray (symbols)) {
|
2963
|
+
const length = symbols.length;
|
2964
|
+
if (length !== 1) {
|
2965
|
+
throw new ArgumentsRequired (this.id + ' fetchPositions() takes an array with exactly one symbol');
|
2966
|
+
}
|
2967
|
+
request['symbol'] = this.marketId (symbols[0]);
|
2968
|
+
}
|
2969
|
+
const defaultType = this.safeString (this.options, 'defaultType', 'linear');
|
2970
|
+
const type = this.safeString (params, 'type', defaultType);
|
2971
|
+
params = this.omit (params, 'type');
|
2972
|
+
let response = undefined;
|
2973
|
+
if (type === 'linear') {
|
2974
|
+
response = await this.privateLinearGetPositionList (this.extend (request, params));
|
2975
|
+
} else if (type === 'inverse') {
|
2976
|
+
response = await this.v2PrivateGetPositionList (this.extend (request, params));
|
2977
|
+
} else if (type === 'inverseFuture') {
|
2978
|
+
response = await this.futuresPrivateGetPositionList (this.extend (request, params));
|
2979
|
+
}
|
2980
|
+
if ((typeof response === 'string') && this.isJsonEncodedObject (response)) {
|
2981
|
+
response = JSON.parse (response);
|
2982
|
+
}
|
2983
|
+
//
|
2984
|
+
// {
|
2985
|
+
// ret_code: 0,
|
2986
|
+
// ret_msg: 'OK',
|
2987
|
+
// ext_code: '',
|
2988
|
+
// ext_info: '',
|
2989
|
+
// result: [] or {} depending on the request
|
2990
|
+
// }
|
2991
|
+
//
|
2992
|
+
return this.safeValue (response, 'result');
|
2993
|
+
}
|
2994
|
+
|
2995
|
+
async setMarginMode (marginType, symbol = undefined, params = {}) {
|
2996
|
+
//
|
2997
|
+
// {
|
2998
|
+
// "ret_code": 0,
|
2999
|
+
// "ret_msg": "ok",
|
3000
|
+
// "ext_code": "",
|
3001
|
+
// "result": null,
|
3002
|
+
// "ext_info": null,
|
3003
|
+
// "time_now": "1577477968.175013",
|
3004
|
+
// "rate_limit_status": 74,
|
3005
|
+
// "rate_limit_reset_ms": 1577477968183,
|
3006
|
+
// "rate_limit": 75
|
3007
|
+
// }
|
3008
|
+
//
|
3009
|
+
const leverage = this.safeValue (params, 'leverage');
|
3010
|
+
if (leverage === undefined) {
|
3011
|
+
throw new ArgumentsRequired (this.id + ' setMarginMode() requires a leverage parameter');
|
3012
|
+
}
|
3013
|
+
marginType = marginType.toUpperCase ();
|
3014
|
+
if (marginType === 'CROSSED') { // * Deprecated, use 'CROSS' instead
|
3015
|
+
marginType = 'CROSS';
|
3016
|
+
}
|
3017
|
+
if ((marginType !== 'ISOLATED') && (marginType !== 'CROSS')) {
|
3018
|
+
throw new BadRequest (this.id + ' setMarginMode() marginType must be either isolated or cross');
|
3019
|
+
}
|
3020
|
+
await this.loadMarkets ();
|
3021
|
+
const market = this.market (symbol);
|
3022
|
+
let method = undefined;
|
3023
|
+
const defaultType = this.safeString (this.options, 'defaultType', 'linear');
|
3024
|
+
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
3025
|
+
const marketType = this.safeString (marketTypes, symbol, defaultType);
|
3026
|
+
const linear = market['linear'] || (marketType === 'linear');
|
3027
|
+
const inverse = (market['swap'] && market['inverse']) || (marketType === 'inverse');
|
3028
|
+
const future = market['future'] || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
|
3029
|
+
if (linear) {
|
3030
|
+
method = 'privateLinearPostPositionSwitchIsolated';
|
3031
|
+
} else if (inverse) {
|
3032
|
+
method = 'v2PrivatePostPositionSwitchIsolated';
|
3033
|
+
} else if (future) {
|
3034
|
+
method = 'privateFuturesPostPositionSwitchIsolated';
|
3035
|
+
}
|
3036
|
+
const isIsolated = (marginType === 'ISOLATED');
|
3037
|
+
const request = {
|
3038
|
+
'symbol': market['id'],
|
3039
|
+
'is_isolated': isIsolated,
|
3040
|
+
'buy_leverage': leverage,
|
3041
|
+
'sell_leverage': leverage,
|
3042
|
+
};
|
3043
|
+
const response = await this[method] (this.extend (request, params));
|
3044
|
+
//
|
3045
|
+
// {
|
3046
|
+
// "ret_code": 0,
|
3047
|
+
// "ret_msg": "OK",
|
3048
|
+
// "ext_code": "",
|
3049
|
+
// "ext_info": "",
|
3050
|
+
// "result": null,
|
3051
|
+
// "time_now": "1585881597.006026",
|
3052
|
+
// "rate_limit_status": 74,
|
3053
|
+
// "rate_limit_reset_ms": 1585881597004,
|
3054
|
+
// "rate_limit": 75
|
3055
|
+
// }
|
3056
|
+
//
|
3057
|
+
return response;
|
3058
|
+
}
|
3059
|
+
|
3060
|
+
async setLeverage (leverage, symbol = undefined, params = {}) {
|
3061
|
+
if (symbol === undefined) {
|
3062
|
+
throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
|
3063
|
+
}
|
3064
|
+
await this.loadMarkets ();
|
3065
|
+
const market = this.market (symbol);
|
3066
|
+
// WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS
|
3067
|
+
// AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS
|
3068
|
+
const defaultType = this.safeString (this.options, 'defaultType', 'linear');
|
3069
|
+
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
3070
|
+
const marketType = this.safeString (marketTypes, symbol, defaultType);
|
3071
|
+
const linear = market['linear'] || (marketType === 'linear');
|
3072
|
+
const inverse = (market['swap'] && market['inverse']) || (marketType === 'inverse');
|
3073
|
+
const future = market['future'] || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
|
3074
|
+
let method = undefined;
|
3075
|
+
if (linear) {
|
3076
|
+
method = 'privateLinearPostPositionSetLeverage';
|
3077
|
+
} else if (inverse) {
|
3078
|
+
method = 'v2PrivatePostPositionLeverageSave';
|
3079
|
+
} else if (future) {
|
3080
|
+
method = 'privateFuturesPostPositionLeverageSave';
|
3081
|
+
}
|
3082
|
+
let buy_leverage = leverage;
|
3083
|
+
let sell_leverage = leverage;
|
3084
|
+
if (params['buy_leverage'] && params['sell_leverage'] && linear) {
|
3085
|
+
buy_leverage = params['buy_leverage'];
|
3086
|
+
sell_leverage = params['sell_leverage'];
|
3087
|
+
} else if (!leverage) {
|
3088
|
+
if (linear) {
|
3089
|
+
throw new ArgumentsRequired (this.id + ' setLeverage() requires either the parameter leverage or params["buy_leverage"] and params["sell_leverage"] for linear contracts');
|
3090
|
+
} else {
|
3091
|
+
throw new ArgumentsRequired (this.id + ' setLeverage() requires parameter leverage for inverse and futures contracts');
|
3092
|
+
}
|
3093
|
+
}
|
3094
|
+
if ((buy_leverage < 1) || (buy_leverage > 100) || (sell_leverage < 1) || (sell_leverage > 100)) {
|
3095
|
+
throw new BadRequest (this.id + ' setLeverage() leverage should be between 1 and 100');
|
3096
|
+
}
|
3097
|
+
const request = {
|
3098
|
+
'symbol': market['id'],
|
3099
|
+
'leverage_only': true,
|
3100
|
+
};
|
3101
|
+
if (!linear) {
|
3102
|
+
request['leverage'] = buy_leverage;
|
3103
|
+
} else {
|
3104
|
+
request['buy_leverage'] = buy_leverage;
|
3105
|
+
request['sell_leverage'] = sell_leverage;
|
3106
|
+
}
|
3107
|
+
return await this[method] (this.extend (request, params));
|
3108
|
+
}
|
3109
|
+
|
3110
|
+
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
3111
|
+
let url = undefined;
|
3112
|
+
if (Array.isArray (api)) {
|
3113
|
+
const type = this.safeString (api, 0);
|
3114
|
+
let section = this.safeString (api, 1);
|
3115
|
+
if (type === 'spot') {
|
3116
|
+
if (section === 'public') {
|
3117
|
+
section = 'v1';
|
3118
|
+
} else {
|
3119
|
+
section += '/v1';
|
3120
|
+
}
|
3121
|
+
}
|
3122
|
+
url = this.implodeHostname (this.urls['api'][type]);
|
3123
|
+
let request = '/' + type + '/' + section + '/' + path;
|
3124
|
+
if ((type === 'spot') || (type === 'quote')) {
|
3125
|
+
if (Object.keys (params).length) {
|
3126
|
+
request += '?' + this.rawencode (params);
|
3127
|
+
}
|
3128
|
+
} else if (section === 'public') {
|
3129
|
+
if (Object.keys (params).length) {
|
3130
|
+
request += '?' + this.rawencode (params);
|
3131
|
+
}
|
3132
|
+
} else if (type === 'public') {
|
3133
|
+
if (Object.keys (params).length) {
|
3134
|
+
request += '?' + this.rawencode (params);
|
3135
|
+
}
|
3136
|
+
} else {
|
3137
|
+
this.checkRequiredCredentials ();
|
3138
|
+
const timestamp = this.nonce ();
|
3139
|
+
const query = this.extend (params, {
|
3140
|
+
'api_key': this.apiKey,
|
3141
|
+
'recv_window': this.options['recvWindow'],
|
3142
|
+
'timestamp': timestamp,
|
3143
|
+
});
|
3144
|
+
const sortedQuery = this.keysort (query);
|
3145
|
+
const auth = this.rawencode (sortedQuery);
|
3146
|
+
const signature = this.hmac (this.encode (auth), this.encode (this.secret));
|
3147
|
+
if (method === 'POST') {
|
3148
|
+
body = this.json (this.extend (query, {
|
3149
|
+
'sign': signature,
|
3150
|
+
}));
|
3151
|
+
headers = {
|
3152
|
+
'Content-Type': 'application/json',
|
3153
|
+
};
|
3154
|
+
} else {
|
3155
|
+
request += '?' + this.urlencode (sortedQuery) + '&sign=' + signature;
|
3156
|
+
}
|
3157
|
+
}
|
3158
|
+
url += request;
|
3159
|
+
} else {
|
3160
|
+
url = this.implodeHostname (this.urls['api'][api]) + '/' + path;
|
3161
|
+
if (api === 'public') {
|
3162
|
+
if (Object.keys (params).length) {
|
3163
|
+
url += '?' + this.rawencode (params);
|
3164
|
+
}
|
3165
|
+
} else if (api === 'private') {
|
3166
|
+
this.checkRequiredCredentials ();
|
3167
|
+
const timestamp = this.nonce ();
|
3168
|
+
const query = this.extend (params, {
|
3169
|
+
'api_key': this.apiKey,
|
3170
|
+
'recv_window': this.options['recvWindow'],
|
3171
|
+
'timestamp': timestamp,
|
3172
|
+
});
|
3173
|
+
const sortedQuery = this.keysort (query);
|
3174
|
+
const auth = this.rawencode (sortedQuery);
|
3175
|
+
const signature = this.hmac (this.encode (auth), this.encode (this.secret));
|
3176
|
+
if (method === 'POST') {
|
3177
|
+
body = this.json (this.extend (query, {
|
3178
|
+
'sign': signature,
|
3179
|
+
}));
|
3180
|
+
headers = {
|
3181
|
+
'Content-Type': 'application/json',
|
3182
|
+
};
|
3183
|
+
} else {
|
3184
|
+
url += '?' + this.urlencode (sortedQuery) + '&sign=' + signature;
|
3185
|
+
}
|
3186
|
+
}
|
3187
|
+
}
|
3188
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
3189
|
+
}
|
3190
|
+
|
3191
|
+
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
3192
|
+
if (!response) {
|
3193
|
+
return; // fallback to default error handler
|
3194
|
+
}
|
3195
|
+
//
|
3196
|
+
// {
|
3197
|
+
// ret_code: 10001,
|
3198
|
+
// ret_msg: 'ReadMapCB: expect { or n, but found \u0000, error ' +
|
3199
|
+
// 'found in #0 byte of ...||..., bigger context ' +
|
3200
|
+
// '...||...',
|
3201
|
+
// ext_code: '',
|
3202
|
+
// ext_info: '',
|
3203
|
+
// result: null,
|
3204
|
+
// time_now: '1583934106.590436'
|
3205
|
+
// }
|
3206
|
+
//
|
3207
|
+
// {
|
3208
|
+
// "retCode":10001,
|
3209
|
+
// "retMsg":"symbol params err",
|
3210
|
+
// "result":{"symbol":"","bid":"","bidIv":"","bidSize":"","ask":"","askIv":"","askSize":"","lastPrice":"","openInterest":"","indexPrice":"","markPrice":"","markPriceIv":"","change24h":"","high24h":"","low24h":"","volume24h":"","turnover24h":"","totalVolume":"","totalTurnover":"","fundingRate":"","predictedFundingRate":"","nextFundingTime":"","countdownHour":"0","predictedDeliveryPrice":"","underlyingPrice":"","delta":"","gamma":"","vega":"","theta":""}
|
3211
|
+
// }
|
3212
|
+
//
|
3213
|
+
const errorCode = this.safeString2 (response, 'ret_code', 'retCode');
|
3214
|
+
if (errorCode !== '0') {
|
3215
|
+
if (errorCode === '30084') {
|
3216
|
+
// not an error
|
3217
|
+
// https://github.com/ccxt/ccxt/issues/11268
|
3218
|
+
// https://github.com/ccxt/ccxt/pull/11624
|
3219
|
+
// POST https://api.bybit.com/v2/private/position/switch-isolated 200 OK
|
3220
|
+
// {"ret_code":30084,"ret_msg":"Isolated not modified","ext_code":"","ext_info":"","result":null,"time_now":"1642005219.937988","rate_limit_status":73,"rate_limit_reset_ms":1642005219894,"rate_limit":75}
|
3221
|
+
return undefined;
|
3222
|
+
}
|
3223
|
+
const feedback = this.id + ' ' + body;
|
3224
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], errorCode, feedback);
|
3225
|
+
this.throwBroadlyMatchedException (this.exceptions['broad'], body, feedback);
|
3226
|
+
throw new ExchangeError (feedback); // unknown message
|
3227
|
+
}
|
3228
|
+
}
|
3229
|
+
|
3230
|
+
async fetchMarketLeverageTiers (symbol, params = {}) {
|
3231
|
+
await this.loadMarkets ();
|
3232
|
+
const request = {};
|
3233
|
+
let market = undefined;
|
3234
|
+
if (symbol !== undefined) {
|
3235
|
+
market = this.market (symbol);
|
3236
|
+
if (market['spot']) {
|
3237
|
+
throw new BadRequest (this.id + ' fetchLeverageTiers() symbol supports contract markets only');
|
3238
|
+
}
|
3239
|
+
request['symbol'] = market['id'];
|
3240
|
+
}
|
3241
|
+
const [ type, query ] = this.handleMarketTypeAndParams ('fetchMarketLeverageTiers', market, params);
|
3242
|
+
const method = this.getSupportedMapping (type, {
|
3243
|
+
'linear': 'publicLinearGetRiskLimit', // Symbol required
|
3244
|
+
'swap': 'publicLinearGetRiskLimit',
|
3245
|
+
'inverse': 'v2PublicGetRiskLimitList', // Symbol not required, could implement fetchLeverageTiers
|
3246
|
+
'future': 'v2PublicGetRiskLimitList',
|
3247
|
+
});
|
3248
|
+
const response = await this[method] (this.extend (request, query));
|
3249
|
+
//
|
3250
|
+
// publicLinearGetRiskLimit
|
3251
|
+
// {
|
3252
|
+
// ret_code: '0',
|
3253
|
+
// ret_msg: 'OK',
|
3254
|
+
// ext_code: '',
|
3255
|
+
// ext_info: '',
|
3256
|
+
// result: [
|
3257
|
+
// {
|
3258
|
+
// id: '11',
|
3259
|
+
// symbol: 'ETHUSDT',
|
3260
|
+
// limit: '800000',
|
3261
|
+
// maintain_margin: '0.01',
|
3262
|
+
// starting_margin: '0.02',
|
3263
|
+
// section: [
|
3264
|
+
// '1', '2', '3',
|
3265
|
+
// '5', '10', '15',
|
3266
|
+
// '25'
|
3267
|
+
// ],
|
3268
|
+
// is_lowest_risk: '1',
|
3269
|
+
// created_at: '2022-02-04 23:30:33.555252',
|
3270
|
+
// updated_at: '2022-02-04 23:30:33.555254',
|
3271
|
+
// max_leverage: '50'
|
3272
|
+
// },
|
3273
|
+
// ...
|
3274
|
+
// ]
|
3275
|
+
// }
|
3276
|
+
//
|
3277
|
+
// v2PublicGetRiskLimitList
|
3278
|
+
// {
|
3279
|
+
// ret_code: '0',
|
3280
|
+
// ret_msg: 'OK',
|
3281
|
+
// ext_code: '',
|
3282
|
+
// ext_info: '',
|
3283
|
+
// result: [
|
3284
|
+
// {
|
3285
|
+
// id: '180',
|
3286
|
+
// is_lowest_risk: '0',
|
3287
|
+
// section: [
|
3288
|
+
// '1', '2', '3',
|
3289
|
+
// '4', '5', '7',
|
3290
|
+
// '8', '9'
|
3291
|
+
// ],
|
3292
|
+
// symbol: 'ETHUSDH22',
|
3293
|
+
// limit: '30000',
|
3294
|
+
// max_leverage: '9',
|
3295
|
+
// starting_margin: '11',
|
3296
|
+
// maintain_margin: '5.5',
|
3297
|
+
// coin: 'ETH',
|
3298
|
+
// created_at: '2021-04-22T15:00:00Z',
|
3299
|
+
// updated_at: '2021-04-22T15:00:00Z'
|
3300
|
+
// },
|
3301
|
+
// ],
|
3302
|
+
// time_now: '1644017569.683191'
|
3303
|
+
// }
|
3304
|
+
//
|
3305
|
+
const result = this.safeValue (response, 'result');
|
3306
|
+
return this.parseMarketLeverageTiers (result, market);
|
3307
|
+
}
|
3308
|
+
|
3309
|
+
parseMarketLeverageTiers (info, market) {
|
3310
|
+
//
|
3311
|
+
// Linear
|
3312
|
+
// [
|
3313
|
+
// {
|
3314
|
+
// id: '11',
|
3315
|
+
// symbol: 'ETHUSDT',
|
3316
|
+
// limit: '800000',
|
3317
|
+
// maintain_margin: '0.01',
|
3318
|
+
// starting_margin: '0.02',
|
3319
|
+
// section: [
|
3320
|
+
// '1', '2', '3',
|
3321
|
+
// '5', '10', '15',
|
3322
|
+
// '25'
|
3323
|
+
// ],
|
3324
|
+
// is_lowest_risk: '1',
|
3325
|
+
// created_at: '2022-02-04 23:30:33.555252',
|
3326
|
+
// updated_at: '2022-02-04 23:30:33.555254',
|
3327
|
+
// max_leverage: '50'
|
3328
|
+
// },
|
3329
|
+
// ...
|
3330
|
+
// ]
|
3331
|
+
//
|
3332
|
+
// Inverse
|
3333
|
+
// [
|
3334
|
+
// {
|
3335
|
+
// id: '180',
|
3336
|
+
// is_lowest_risk: '0',
|
3337
|
+
// section: [
|
3338
|
+
// '1', '2', '3',
|
3339
|
+
// '4', '5', '7',
|
3340
|
+
// '8', '9'
|
3341
|
+
// ],
|
3342
|
+
// symbol: 'ETHUSDH22',
|
3343
|
+
// limit: '30000',
|
3344
|
+
// max_leverage: '9',
|
3345
|
+
// starting_margin: '11',
|
3346
|
+
// maintain_margin: '5.5',
|
3347
|
+
// coin: 'ETH',
|
3348
|
+
// created_at: '2021-04-22T15:00:00Z',
|
3349
|
+
// updated_at: '2021-04-22T15:00:00Z'
|
3350
|
+
// }
|
3351
|
+
// ...
|
3352
|
+
// ]
|
3353
|
+
//
|
3354
|
+
let minNotional = 0;
|
3355
|
+
const tiers = [];
|
3356
|
+
for (let i = 0; i < info.length; i++) {
|
3357
|
+
const item = info[i];
|
3358
|
+
const maxNotional = this.safeNumber (item, 'limit');
|
3359
|
+
tiers.push ({
|
3360
|
+
'tier': this.sum (i, 1),
|
3361
|
+
'currency': market['base'],
|
3362
|
+
'minNotional': minNotional,
|
3363
|
+
'maxNotional': maxNotional,
|
3364
|
+
'maintenanceMarginRate': this.safeNumber (item, 'maintain_margin'),
|
3365
|
+
'maxLeverage': this.safeNumber (item, 'max_leverage'),
|
3366
|
+
'info': item,
|
3367
|
+
});
|
3368
|
+
minNotional = maxNotional;
|
3369
|
+
}
|
3370
|
+
return tiers;
|
3371
|
+
}
|
3372
|
+
};
|