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/zb.js
ADDED
@@ -0,0 +1,4088 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const { BadRequest, BadSymbol, ExchangeError, ArgumentsRequired, AuthenticationError, InsufficientFunds, NotSupported, OrderNotFound, ExchangeNotAvailable, RateLimitExceeded, PermissionDenied, InvalidOrder, InvalidAddress, OnMaintenance, RequestTimeout, AccountSuspended, NetworkError, DDoSProtection, DuplicateOrderId, BadResponse } = require ('./base/errors');
|
7
|
+
const Precise = require ('./base/Precise');
|
8
|
+
|
9
|
+
// ---------------------------------------------------------------------------
|
10
|
+
|
11
|
+
module.exports = class zb extends Exchange {
|
12
|
+
describe () {
|
13
|
+
return this.deepExtend (super.describe (), {
|
14
|
+
'id': 'zb',
|
15
|
+
'name': 'ZB',
|
16
|
+
'countries': [ 'CN' ],
|
17
|
+
'rateLimit': 100,
|
18
|
+
'version': 'v1',
|
19
|
+
'certified': true,
|
20
|
+
'pro': true,
|
21
|
+
'has': {
|
22
|
+
'CORS': undefined,
|
23
|
+
'spot': true,
|
24
|
+
'margin': true,
|
25
|
+
'swap': true,
|
26
|
+
'future': undefined,
|
27
|
+
'option': undefined,
|
28
|
+
'addMargin': true,
|
29
|
+
'cancelAllOrders': true,
|
30
|
+
'cancelOrder': true,
|
31
|
+
'createMarketOrder': undefined,
|
32
|
+
'createOrder': true,
|
33
|
+
'createReduceOnlyOrder': false,
|
34
|
+
'createStopLimitOrder': true,
|
35
|
+
'createStopMarketOrder': true,
|
36
|
+
'createStopOrder': true,
|
37
|
+
'fetchBalance': true,
|
38
|
+
'fetchBorrowRate': true,
|
39
|
+
'fetchBorrowRateHistories': false,
|
40
|
+
'fetchBorrowRateHistory': false,
|
41
|
+
'fetchBorrowRates': true,
|
42
|
+
'fetchCanceledOrders': true,
|
43
|
+
'fetchClosedOrders': true,
|
44
|
+
'fetchCurrencies': true,
|
45
|
+
'fetchDepositAddress': true,
|
46
|
+
'fetchDepositAddresses': true,
|
47
|
+
'fetchDeposits': true,
|
48
|
+
'fetchFundingHistory': false,
|
49
|
+
'fetchFundingRate': true,
|
50
|
+
'fetchFundingRateHistory': true,
|
51
|
+
'fetchFundingRates': true,
|
52
|
+
'fetchLedger': true,
|
53
|
+
'fetchLeverage': false,
|
54
|
+
'fetchLeverageTiers': false,
|
55
|
+
'fetchMarketLeverageTiers': false,
|
56
|
+
'fetchMarkets': true,
|
57
|
+
'fetchOHLCV': true,
|
58
|
+
'fetchOpenOrders': true,
|
59
|
+
'fetchOrder': true,
|
60
|
+
'fetchOrderBook': true,
|
61
|
+
'fetchOrders': true,
|
62
|
+
'fetchPosition': true,
|
63
|
+
'fetchPositions': true,
|
64
|
+
'fetchPositionsRisk': false,
|
65
|
+
'fetchPremiumIndexOHLCV': false,
|
66
|
+
'fetchTicker': true,
|
67
|
+
'fetchTickers': true,
|
68
|
+
'fetchTrades': true,
|
69
|
+
'fetchTradingFee': false,
|
70
|
+
'fetchTradingFees': false,
|
71
|
+
'fetchWithdrawals': true,
|
72
|
+
'reduceMargin': true,
|
73
|
+
'setLeverage': true,
|
74
|
+
'setMarginMode': false,
|
75
|
+
'setPositionMode': false,
|
76
|
+
'transfer': true,
|
77
|
+
'withdraw': true,
|
78
|
+
},
|
79
|
+
'timeframes': {
|
80
|
+
'1m': '1m',
|
81
|
+
'3m': '3m',
|
82
|
+
'5m': '5m',
|
83
|
+
'15m': '15m',
|
84
|
+
'30m': '30m',
|
85
|
+
'1h': '1h',
|
86
|
+
'2h': '2h',
|
87
|
+
'4h': '4h',
|
88
|
+
'6h': '6h',
|
89
|
+
'12h': '12h',
|
90
|
+
'1d': '1d',
|
91
|
+
'3d': '3d',
|
92
|
+
'5d': '5d',
|
93
|
+
'1w': '1w',
|
94
|
+
},
|
95
|
+
'hostname': 'zb.com', // zb.cafe for users in China
|
96
|
+
'urls': {
|
97
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/32859187-cd5214f0-ca5e-11e7-967d-96568e2e2bd1.jpg',
|
98
|
+
'api': {
|
99
|
+
'spot': {
|
100
|
+
'v1': {
|
101
|
+
'public': 'https://api.{hostname}/data',
|
102
|
+
'private': 'https://trade.{hostname}/api',
|
103
|
+
},
|
104
|
+
},
|
105
|
+
'contract': {
|
106
|
+
'v1': {
|
107
|
+
'public': 'https://fapi.{hostname}/api/public',
|
108
|
+
},
|
109
|
+
'v2': {
|
110
|
+
'public': 'https://fapi.{hostname}/Server/api',
|
111
|
+
'private': 'https://fapi.{hostname}/Server/api',
|
112
|
+
},
|
113
|
+
},
|
114
|
+
},
|
115
|
+
'www': 'https://www.zb.com',
|
116
|
+
'doc': 'https://www.zb.com/i/developer',
|
117
|
+
'fees': 'https://www.zb.com/i/rate',
|
118
|
+
'referral': {
|
119
|
+
'url': 'https://www.zbex.club/en/register?ref=4301lera',
|
120
|
+
'discount': 0.16,
|
121
|
+
},
|
122
|
+
},
|
123
|
+
'api': {
|
124
|
+
'spot': {
|
125
|
+
'v1': {
|
126
|
+
'public': {
|
127
|
+
'get': [
|
128
|
+
'markets',
|
129
|
+
'ticker',
|
130
|
+
'allTicker',
|
131
|
+
'depth',
|
132
|
+
'trades',
|
133
|
+
'kline',
|
134
|
+
'getGroupMarkets',
|
135
|
+
'getFeeInfo',
|
136
|
+
],
|
137
|
+
},
|
138
|
+
'private': {
|
139
|
+
'get': [
|
140
|
+
// spot API
|
141
|
+
'order',
|
142
|
+
'orderMoreV2',
|
143
|
+
'cancelOrder',
|
144
|
+
'getOrder',
|
145
|
+
'getOrders',
|
146
|
+
'getOrdersNew',
|
147
|
+
'getOrdersIgnoreTradeType',
|
148
|
+
'getUnfinishedOrdersIgnoreTradeType',
|
149
|
+
'getFinishedAndPartialOrders',
|
150
|
+
'getAccountInfo',
|
151
|
+
'getUserAddress',
|
152
|
+
'getPayinAddress',
|
153
|
+
'getWithdrawAddress',
|
154
|
+
'getWithdrawRecord',
|
155
|
+
'getChargeRecord',
|
156
|
+
'getCnyWithdrawRecord',
|
157
|
+
'getCnyChargeRecord',
|
158
|
+
'withdraw',
|
159
|
+
// sub accounts
|
160
|
+
'addSubUser',
|
161
|
+
'getSubUserList',
|
162
|
+
'doTransferFunds',
|
163
|
+
'createSubUserKey', // removed on 2021-03-16 according to the update log in the API doc
|
164
|
+
// leverage API
|
165
|
+
'getLeverAssetsInfo',
|
166
|
+
'getLeverBills',
|
167
|
+
'transferInLever',
|
168
|
+
'transferOutLever',
|
169
|
+
'loan',
|
170
|
+
'cancelLoan',
|
171
|
+
'getLoans',
|
172
|
+
'getLoanRecords',
|
173
|
+
'borrow',
|
174
|
+
'autoBorrow',
|
175
|
+
'repay',
|
176
|
+
'doAllRepay',
|
177
|
+
'getRepayments',
|
178
|
+
'getFinanceRecords',
|
179
|
+
'changeInvestMark',
|
180
|
+
'changeLoop',
|
181
|
+
// cross API
|
182
|
+
'getCrossAssets',
|
183
|
+
'getCrossBills',
|
184
|
+
'transferInCross',
|
185
|
+
'transferOutCross',
|
186
|
+
'doCrossLoan',
|
187
|
+
'doCrossRepay',
|
188
|
+
'getCrossRepayRecords',
|
189
|
+
],
|
190
|
+
},
|
191
|
+
},
|
192
|
+
},
|
193
|
+
'contract': {
|
194
|
+
'v1': {
|
195
|
+
'public': {
|
196
|
+
'get': [
|
197
|
+
'depth',
|
198
|
+
'fundingRate',
|
199
|
+
'indexKline',
|
200
|
+
'indexPrice',
|
201
|
+
'kline',
|
202
|
+
'markKline',
|
203
|
+
'markPrice',
|
204
|
+
'ticker',
|
205
|
+
'trade',
|
206
|
+
],
|
207
|
+
},
|
208
|
+
},
|
209
|
+
'v2': {
|
210
|
+
'public': {
|
211
|
+
'get': [
|
212
|
+
'allForceOrders',
|
213
|
+
'config/marketList',
|
214
|
+
'topLongShortAccountRatio',
|
215
|
+
'topLongShortPositionRatio',
|
216
|
+
'fundingRate',
|
217
|
+
'premiumIndex',
|
218
|
+
],
|
219
|
+
},
|
220
|
+
'private': {
|
221
|
+
'get': [
|
222
|
+
'Fund/balance',
|
223
|
+
'Fund/getAccount',
|
224
|
+
'Fund/getBill',
|
225
|
+
'Fund/getBillTypeList',
|
226
|
+
'Fund/marginHistory',
|
227
|
+
'Positions/getPositions',
|
228
|
+
'Positions/getNominalValue',
|
229
|
+
'Positions/marginInfo',
|
230
|
+
'setting/get',
|
231
|
+
'trade/getAllOrders',
|
232
|
+
'trade/getOrder',
|
233
|
+
'trade/getOrderAlgos',
|
234
|
+
'trade/getTradeList',
|
235
|
+
'trade/getUndoneOrders',
|
236
|
+
'trade/tradeHistory',
|
237
|
+
],
|
238
|
+
'post': [
|
239
|
+
'activity/buyTicket',
|
240
|
+
'Fund/transferFund',
|
241
|
+
'Positions/setMarginCoins',
|
242
|
+
'Positions/updateAppendUSDValue',
|
243
|
+
'Positions/updateMargin',
|
244
|
+
'setting/setLeverage',
|
245
|
+
'trade/batchOrder',
|
246
|
+
'trade/batchCancelOrder',
|
247
|
+
'trade/cancelAlgos',
|
248
|
+
'trade/cancelAllOrders',
|
249
|
+
'trade/cancelOrder',
|
250
|
+
'trade/order',
|
251
|
+
'trade/orderAlgo',
|
252
|
+
'trade/updateOrderAlgo',
|
253
|
+
],
|
254
|
+
},
|
255
|
+
},
|
256
|
+
},
|
257
|
+
},
|
258
|
+
'fees': {
|
259
|
+
'funding': {
|
260
|
+
'withdraw': {},
|
261
|
+
},
|
262
|
+
'trading': {
|
263
|
+
'maker': this.parseNumber ('0.002'),
|
264
|
+
'taker': this.parseNumber ('0.002'),
|
265
|
+
},
|
266
|
+
},
|
267
|
+
'commonCurrencies': {
|
268
|
+
'ANG': 'Anagram',
|
269
|
+
'ENT': 'ENTCash',
|
270
|
+
'BCHABC': 'BCHABC', // conflict with BCH / BCHA
|
271
|
+
'BCHSV': 'BCHSV', // conflict with BCH / BSV
|
272
|
+
},
|
273
|
+
'options': {
|
274
|
+
'timeframes': {
|
275
|
+
'spot': {
|
276
|
+
'1m': '1min',
|
277
|
+
'3m': '3min',
|
278
|
+
'5m': '5min',
|
279
|
+
'15m': '15min',
|
280
|
+
'30m': '30min',
|
281
|
+
'1h': '1hour',
|
282
|
+
'2h': '2hour',
|
283
|
+
'4h': '4hour',
|
284
|
+
'6h': '6hour',
|
285
|
+
'12h': '12hour',
|
286
|
+
'1d': '1day',
|
287
|
+
'3d': '3day',
|
288
|
+
'1w': '1week',
|
289
|
+
},
|
290
|
+
'swap': {
|
291
|
+
'1m': '1M',
|
292
|
+
'5m': '5M',
|
293
|
+
'15m': '15M',
|
294
|
+
'30m': '30M',
|
295
|
+
'1h': '1H',
|
296
|
+
'6h': '6H',
|
297
|
+
'1d': '1D',
|
298
|
+
'5d': '5D',
|
299
|
+
},
|
300
|
+
},
|
301
|
+
},
|
302
|
+
'exceptions': {
|
303
|
+
'ws': {
|
304
|
+
// '1000': ExchangeError, // The call is successful.
|
305
|
+
'1001': ExchangeError, // General error prompt
|
306
|
+
'1002': ExchangeError, // Internal Error
|
307
|
+
'1003': AuthenticationError, // Fail to verify
|
308
|
+
'1004': AuthenticationError, // The transaction password is locked
|
309
|
+
'1005': AuthenticationError, // Wrong transaction password, please check it and re-enter。
|
310
|
+
'1006': PermissionDenied, // Real-name authentication is pending approval or unapproved
|
311
|
+
'1007': ExchangeError, // Channel does not exist
|
312
|
+
'1009': OnMaintenance, // This interface is under maintenance
|
313
|
+
'1010': ExchangeNotAvailable, // Not available now
|
314
|
+
'1012': PermissionDenied, // Insufficient permissions
|
315
|
+
'1013': ExchangeError, // Cannot trade, please contact email: support@zb.cn for support.
|
316
|
+
'1014': ExchangeError, // Cannot sell during the pre-sale period
|
317
|
+
'2001': InsufficientFunds, // Insufficient CNY account balance
|
318
|
+
'2002': InsufficientFunds, // Insufficient BTC account balance
|
319
|
+
'2003': InsufficientFunds, // Insufficient LTC account balance
|
320
|
+
'2005': InsufficientFunds, // Insufficient ETH account balance
|
321
|
+
'2006': InsufficientFunds, // ETCInsufficient account balance
|
322
|
+
'2007': InsufficientFunds, // BTSInsufficient account balance
|
323
|
+
'2008': InsufficientFunds, // EOSInsufficient account balance
|
324
|
+
'2009': InsufficientFunds, // BCCInsufficient account balance
|
325
|
+
'3001': OrderNotFound, // Order not found or is completed
|
326
|
+
'3002': InvalidOrder, // Invalid amount
|
327
|
+
'3003': InvalidOrder, // Invalid quantity
|
328
|
+
'3004': AuthenticationError, // User does not exist
|
329
|
+
'3005': BadRequest, // Invalid parameter
|
330
|
+
'3006': PermissionDenied, // Invalid IP or not consistent with the bound IP
|
331
|
+
'3007': RequestTimeout, // The request time has expired
|
332
|
+
'3008': ExchangeError, // Transaction not found
|
333
|
+
'3009': InvalidOrder, // The price exceeds the limit
|
334
|
+
'3010': PermissionDenied, // It fails to place an order, due to you have set up to prohibit trading of this market.
|
335
|
+
'3011': InvalidOrder, // The entrusted price is abnormal, please modify it and place order again
|
336
|
+
'3012': InvalidOrder, // Duplicate custom customerOrderId
|
337
|
+
'4001': AccountSuspended, // APIThe interface is locked for one hour
|
338
|
+
'4002': RateLimitExceeded, // Request too frequently
|
339
|
+
},
|
340
|
+
'exact': {
|
341
|
+
// '1000': 'Successful operation',
|
342
|
+
'10001': ExchangeError, // Operation failed
|
343
|
+
'10002': PermissionDenied, // Operation is forbidden
|
344
|
+
'10003': BadResponse, // Data existed
|
345
|
+
'10004': BadResponse, // Date not exist
|
346
|
+
'10005': PermissionDenied, // Forbidden to access the interface
|
347
|
+
'10006': BadRequest, // Currency invalid or expired
|
348
|
+
'10007': ExchangeError, // {0}
|
349
|
+
'10008': ExchangeError, // Operation failed: {0}
|
350
|
+
'10009': ExchangeError, // URL error
|
351
|
+
'1001': ExchangeError, // 'General error message',
|
352
|
+
'10010': AuthenticationError, // API KEY not exist
|
353
|
+
'10011': AuthenticationError, // API KEY CLOSED
|
354
|
+
'10012': AccountSuspended, // User API has been frozen, please contact customer service for processing
|
355
|
+
'10013': AuthenticationError, // API verification failed
|
356
|
+
'10014': AuthenticationError, // Invalid signature(1001)
|
357
|
+
'10015': AuthenticationError, // Invalid signature(1002)
|
358
|
+
'10016': AuthenticationError, // Invalid ip
|
359
|
+
'10017': PermissionDenied, // Permission denied
|
360
|
+
'10018': AccountSuspended, // User has been frozen, please contact customer service
|
361
|
+
'10019': RequestTimeout, // Request time has expired
|
362
|
+
'1002': ExchangeError, // 'Internal error',
|
363
|
+
'10020': BadRequest, // {0}Parameter cannot be empty
|
364
|
+
'10021': BadRequest, // {0}Invalid parameter
|
365
|
+
'10022': BadRequest, // Request method error
|
366
|
+
'10023': RateLimitExceeded, // Request frequency is too fast, exceeding the limit allowed by the interface
|
367
|
+
'10024': AuthenticationError, // Login failed
|
368
|
+
'10025': ExchangeError, // Non-personal operation
|
369
|
+
'10026': NetworkError, // Failed to request interface, please try again
|
370
|
+
'10027': RequestTimeout, // Timed out, please try again later
|
371
|
+
'10028': ExchangeNotAvailable, // System busy, please try again later
|
372
|
+
'10029': DDoSProtection, // Frequent operation, please try again later
|
373
|
+
'1003': AuthenticationError, // 'Verification does not pass',
|
374
|
+
'10030': BadRequest, // Currency already exist
|
375
|
+
'10031': BadRequest, // Currency does not exist
|
376
|
+
'10032': BadRequest, // Market existed
|
377
|
+
'10033': BadRequest, // Market not exist
|
378
|
+
'10034': BadRequest, // Currency error
|
379
|
+
'10035': BadRequest, // Market not open
|
380
|
+
'10036': BadRequest, // Ineffective market type
|
381
|
+
'10037': ArgumentsRequired, // User id cannot be empty
|
382
|
+
'10038': BadRequest, // Market id cannot be empty
|
383
|
+
'10039': BadResponse, // Failed to get mark price
|
384
|
+
'1004': AuthenticationError, // 'Funding security password lock',
|
385
|
+
'10040': BadResponse, // Failed to obtain the opening margin configuration
|
386
|
+
'10041': BadResponse, // Failed to obtain maintenance margin allocation
|
387
|
+
'10042': ExchangeError, // Avg. price error
|
388
|
+
'10043': ExchangeError, // Abnormal acquisition of liquidation price
|
389
|
+
'10044': ExchangeError, // Unrealized profit and loss acquisition exception
|
390
|
+
'10045': ExchangeError, // jdbcData source acquisition failed
|
391
|
+
'10046': ExchangeError, // Invalid position opening direction
|
392
|
+
'10047': ExchangeError, // The maximum position allowed by the current leverage multiple has been exceeded
|
393
|
+
'10048': ExchangeError, // The maximum allowable order quantity has been exceeded
|
394
|
+
'10049': NetworkError, // Failed to get the latest price
|
395
|
+
'1005': AuthenticationError, // 'Funds security password is incorrect, please confirm and re-enter.',
|
396
|
+
'1006': AuthenticationError, // 'Real-name certification pending approval or audit does not pass',
|
397
|
+
'1009': ExchangeNotAvailable, // 'This interface is under maintenance',
|
398
|
+
'1010': ExchangeNotAvailable, // Not available now
|
399
|
+
'10100': OnMaintenance, // Sorry! System maintenance, stop operation
|
400
|
+
'1012': PermissionDenied, // Insufficient permissions
|
401
|
+
'1013': ExchangeError, // Cannot trade, please contact email: support@zb.cn for support.
|
402
|
+
'1014': ExchangeError, // Cannot sell during the pre-sale period
|
403
|
+
'11000': ExchangeError, // Funding change failed
|
404
|
+
'11001': ExchangeError, // Position change failed
|
405
|
+
'110011': ExchangeError, // Exceeds the maximum leverage allowed by the position
|
406
|
+
'11002': ExchangeError, // Funding not exist
|
407
|
+
'11003': ExchangeError, // Freeze records not exist
|
408
|
+
'11004': InsufficientFunds, // Insufficient frozen funds
|
409
|
+
'11005': InvalidOrder, // Insufficient positions
|
410
|
+
'11006': InsufficientFunds, // Insufficient frozen positions
|
411
|
+
'11007': OrderNotFound, // Position not exist
|
412
|
+
'11008': ExchangeError, // The contract have positions, cannot be modified
|
413
|
+
'11009': ExchangeError, // Failed to query data
|
414
|
+
'110110': ExchangeError, // Exceed the market's maximum leverage
|
415
|
+
'11012': InsufficientFunds, // Insufficient margin
|
416
|
+
'11013': ExchangeError, // Exceeding accuracy limit
|
417
|
+
'11014': ExchangeError, // Invalid bill type
|
418
|
+
'11015': AuthenticationError, // Failed to add default account
|
419
|
+
'11016': AuthenticationError, // Account not exist
|
420
|
+
'11017': ExchangeError, // Funds are not frozen or unfrozen
|
421
|
+
'11018': InsufficientFunds, // Insufficient funds
|
422
|
+
'11019': ExchangeError, // Bill does not exist
|
423
|
+
'11021': InsufficientFunds, // Inconsistent currency for funds transfer
|
424
|
+
'11023': ExchangeError, // Same transaction currency
|
425
|
+
'11030': PermissionDenied, // Position is locked, the operation is prohibited
|
426
|
+
'11031': ExchangeError, // The number of bill changes is zero
|
427
|
+
'11032': ExchangeError, // The same request is being processed, please do not submit it repeatedly
|
428
|
+
'11033': ArgumentsRequired, // Position configuration data is empty
|
429
|
+
'11034': ExchangeError, // Funding fee is being settled, please do not operate
|
430
|
+
'12000': InvalidOrder, // Invalid order price
|
431
|
+
'12001': InvalidOrder, // Invalid order amount
|
432
|
+
'12002': InvalidOrder, // Invalid order type
|
433
|
+
'12003': InvalidOrder, // Invalid price accuracy
|
434
|
+
'12004': InvalidOrder, // Invalid quantity precision
|
435
|
+
'12005': InvalidOrder, // order value less than the minimum or greater than the maximum
|
436
|
+
'12006': InvalidOrder, // Customize's order number format is wrong
|
437
|
+
'12007': InvalidOrder, // Direction error
|
438
|
+
'12008': InvalidOrder, // Order type error
|
439
|
+
'12009': InvalidOrder, // Commission type error
|
440
|
+
'12010': InvalidOrder, // Failed to place the order, the loss of the order placed at this price will exceed margin
|
441
|
+
'12011': InvalidOrder, // it's not a buz order
|
442
|
+
'12012': OrderNotFound, // order not exist
|
443
|
+
'12013': InvalidOrder, // Order user does not match
|
444
|
+
'12014': InvalidOrder, // Order is still in transaction
|
445
|
+
'12015': InvalidOrder, // Order preprocessing failed
|
446
|
+
'12016': InvalidOrder, // Order cannot be canceled
|
447
|
+
'12017': InvalidOrder, // Transaction Record not exist
|
448
|
+
'12018': InvalidOrder, // Order failed
|
449
|
+
'12019': ArgumentsRequired, // extend parameter cannot be empty
|
450
|
+
'12020': ExchangeError, // extend Parameter error
|
451
|
+
'12021': InvalidOrder, // The order price is not within the price limit rules!
|
452
|
+
'12022': InvalidOrder, // Stop placing an order while the system is calculating the fund fee
|
453
|
+
'12023': OrderNotFound, // There are no positions to close
|
454
|
+
'12024': InvalidOrder, // Orders are prohibited, stay tuned!
|
455
|
+
'12025': InvalidOrder, // Order cancellation is prohibited, so stay tuned!
|
456
|
+
'12026': DuplicateOrderId, // Order failed, customize order number exists
|
457
|
+
'12027': ExchangeNotAvailable, // System busy, please try again later
|
458
|
+
'12028': InvalidOrder, // The market has banned trading
|
459
|
+
'12029': InvalidOrder, // Forbidden place order, stay tuned
|
460
|
+
'12201': InvalidOrder, // Delegation strategy does not exist or the status has changed
|
461
|
+
'12202': InvalidOrder, // Delegation strategy has been changed, cannot be canceled
|
462
|
+
'12203': InvalidOrder, // Wrong order type
|
463
|
+
'12204': InvalidOrder, // Invalid trigger price
|
464
|
+
'12205': InvalidOrder, // The trigger price must be greater than the market’s selling price or lower than the buying price.
|
465
|
+
'12206': InvalidOrder, // Direction and order type do not match
|
466
|
+
'12207': RateLimitExceeded, // Submission failed, exceeding the allowed limit
|
467
|
+
'13001': AuthenticationError, // User not exist
|
468
|
+
'13002': PermissionDenied, // User did not activate futures
|
469
|
+
// '13003': AuthenticationError, // User is locked
|
470
|
+
'13003': InvalidOrder, // Margin gear is not continuous
|
471
|
+
'13004': InvalidOrder, // The margin quick calculation amount is less than 0
|
472
|
+
'13005': RateLimitExceeded, // You have exceeded the number of exports that day
|
473
|
+
'13006': ExchangeError, // No markets are bookmarked
|
474
|
+
'13007': ExchangeError, // Market not favorited
|
475
|
+
'13008': ExchangeError, // Not in any market user whitelist
|
476
|
+
'13009': ExchangeError, // Not in the whitelist of users in this market
|
477
|
+
'14000': ExchangeError, // {0}not support
|
478
|
+
'14001': AuthenticationError, // Already logged in, no need to log in multiple times
|
479
|
+
'14002': AuthenticationError, // Not logged in yet, please log in before subscribing
|
480
|
+
'14003': ExchangeError, // This is a channel for one-time queries, no need to unsubscribe
|
481
|
+
'14100': ExchangeError, // Accuracy does not support
|
482
|
+
'14101': RateLimitExceeded, // Request exceeded frequency limit
|
483
|
+
'14200': ArgumentsRequired, // id empty
|
484
|
+
'14300': ExchangeError, // activity not exist
|
485
|
+
'14301': ExchangeError, // The event has been opened and cannot be admitted
|
486
|
+
'14302': ExchangeError, // The purchase time has passed and cannot be admitted
|
487
|
+
'14303': ExchangeError, // Not yet open for the purchase
|
488
|
+
'14305': ExchangeError, // Cannot enter, the maximum number of returns has been exceeded
|
489
|
+
'14306': ExchangeError, // Cannot repeat admission
|
490
|
+
'14307': InvalidOrder, // Unable to cancel, status has been changed
|
491
|
+
'14308': InvalidOrder, // Unable to cancel, the amount does not match
|
492
|
+
'14309': ExchangeError, // Activity has not started
|
493
|
+
'14310': NotSupported, // Activity is over
|
494
|
+
'14311': NotSupported, // The activity does not support orders placed in this market
|
495
|
+
'14312': ExchangeError, // You have not participated in this activity
|
496
|
+
'14313': PermissionDenied, // Sorry! The purchase failed, the maximum number of participants has been reached
|
497
|
+
'14314': ExchangeError, // Active period id error
|
498
|
+
'2001': InsufficientFunds, // 'Insufficient CNY Balance',
|
499
|
+
'2002': InsufficientFunds, // 'Insufficient BTC Balance',
|
500
|
+
'2003': InsufficientFunds, // 'Insufficient LTC Balance',
|
501
|
+
'2005': InsufficientFunds, // 'Insufficient ETH Balance',
|
502
|
+
'2006': InsufficientFunds, // 'Insufficient ETC Balance',
|
503
|
+
'2007': InsufficientFunds, // 'Insufficient BTS Balance',
|
504
|
+
'2008': InsufficientFunds, // EOSInsufficient account balance
|
505
|
+
'2009': InsufficientFunds, // 'Account balance is not enough',
|
506
|
+
'3001': OrderNotFound, // 'Pending orders not found',
|
507
|
+
'3002': InvalidOrder, // 'Invalid price',
|
508
|
+
'3003': InvalidOrder, // 'Invalid amount',
|
509
|
+
'3004': AuthenticationError, // 'User does not exist',
|
510
|
+
'3005': BadRequest, // 'Invalid parameter',
|
511
|
+
'3006': AuthenticationError, // 'Invalid IP or inconsistent with the bound IP',
|
512
|
+
'3007': AuthenticationError, // 'The request time has expired',
|
513
|
+
'3008': OrderNotFound, // 'Transaction records not found',
|
514
|
+
'3009': InvalidOrder, // 'The price exceeds the limit',
|
515
|
+
'3010': PermissionDenied, // It fails to place an order, due to you have set up to prohibit trading of this market.
|
516
|
+
'3011': InvalidOrder, // 'The entrusted price is abnormal, please modify it and place order again',
|
517
|
+
'3012': InvalidOrder, // Duplicate custom customerOrderId
|
518
|
+
'4001': ExchangeNotAvailable, // 'API interface is locked or not enabled',
|
519
|
+
'4002': RateLimitExceeded, // 'Request too often',
|
520
|
+
'9999': ExchangeError, // Unknown error
|
521
|
+
},
|
522
|
+
'broad': {
|
523
|
+
'提币地址有误, 请先添加提币地址。': InvalidAddress, // {"code":1001,"message":"提币地址有误,请先添加提币地址。"}
|
524
|
+
'资金不足,无法划账': InsufficientFunds, // {"code":1001,"message":"资金不足,无法划账"}
|
525
|
+
'响应超时': RequestTimeout, // {"code":1001,"message":"响应超时"}
|
526
|
+
},
|
527
|
+
},
|
528
|
+
});
|
529
|
+
}
|
530
|
+
|
531
|
+
async fetchMarkets (params = {}) {
|
532
|
+
const markets = await this.spotV1PublicGetMarkets (params);
|
533
|
+
//
|
534
|
+
// {
|
535
|
+
// "zb_qc":{
|
536
|
+
// "amountScale":2,
|
537
|
+
// "minAmount":0.01,
|
538
|
+
// "minSize":5,
|
539
|
+
// "priceScale":4,
|
540
|
+
// },
|
541
|
+
// }
|
542
|
+
//
|
543
|
+
let contracts = undefined;
|
544
|
+
try {
|
545
|
+
// https://github.com/ZBFuture/docs_en/blob/main/API%20V2%20_en.md#7-public-markethttp
|
546
|
+
// https://fapi.zb.com/Server/api/v2/config/marketList 502 Bad Gateway
|
547
|
+
contracts = await this.contractV2PublicGetConfigMarketList (params);
|
548
|
+
} catch (e) {
|
549
|
+
contracts = {};
|
550
|
+
}
|
551
|
+
//
|
552
|
+
// {
|
553
|
+
// BTC_USDT: {
|
554
|
+
// symbol: 'BTC_USDT',
|
555
|
+
// buyerCurrencyId: '6',
|
556
|
+
// contractType: '1',
|
557
|
+
// defaultMarginMode: '1',
|
558
|
+
// marketType: '2',
|
559
|
+
// historyDBName: 'trade_history_readonly.dbc',
|
560
|
+
// defaultLeverage: '20',
|
561
|
+
// id: '100',
|
562
|
+
// canCancelOrder: true,
|
563
|
+
// area: '1',
|
564
|
+
// mixMarginCoinName: 'usdt',
|
565
|
+
// fundingRateRatio: '0.25',
|
566
|
+
// marginCurrencyName: 'usdt',
|
567
|
+
// minTradeMoney: '0.0001',
|
568
|
+
// enableTime: '1638954000000',
|
569
|
+
// maxTradeMoney: '10000000',
|
570
|
+
// canTrade: true,
|
571
|
+
// maxLeverage: '125',
|
572
|
+
// defaultPositionsMode: '2',
|
573
|
+
// onlyWhitelistVisible: false,
|
574
|
+
// riskWarnRatio: '0.8',
|
575
|
+
// marginDecimal: '8',
|
576
|
+
// spot: false,
|
577
|
+
// status: '1',
|
578
|
+
// amountDecimal: '3',
|
579
|
+
// leverage: false,
|
580
|
+
// minAmount: '0.001',
|
581
|
+
// canOrder: true,
|
582
|
+
// duration: '1',
|
583
|
+
// feeDecimal: '8',
|
584
|
+
// sellerCurrencyId: '1',
|
585
|
+
// maxAmount: '1000',
|
586
|
+
// canOpenPosition: true,
|
587
|
+
// isSupportMixMargin: false,
|
588
|
+
// markPriceLimitRate: '0.05',
|
589
|
+
// marginCurrencyId: '6',
|
590
|
+
// stopFundingFee: false,
|
591
|
+
// priceDecimal: '2',
|
592
|
+
// lightenUpFeeRate: '0',
|
593
|
+
// futures: true,
|
594
|
+
// sellerCurrencyName: 'btc',
|
595
|
+
// marketPriceLimitRate: '0.05',
|
596
|
+
// canRebate: true,
|
597
|
+
// marketName: 'BTC_USDT',
|
598
|
+
// depth: [ 0.01, 0.1, 1 ],
|
599
|
+
// createTime: '1607590430094',
|
600
|
+
// mixMarginCoinIds: [ 6 ],
|
601
|
+
// buyerCurrencyName: 'usdt',
|
602
|
+
// stopService: false
|
603
|
+
// },
|
604
|
+
// }
|
605
|
+
//
|
606
|
+
const contractsData = this.safeValue (contracts, 'data', []);
|
607
|
+
const contractsById = this.indexBy (contractsData, 'marketName');
|
608
|
+
const dataById = this.deepExtend (contractsById, markets);
|
609
|
+
const keys = Object.keys (dataById);
|
610
|
+
const result = [];
|
611
|
+
for (let i = 0; i < keys.length; i++) {
|
612
|
+
const id = keys[i];
|
613
|
+
const market = dataById[id];
|
614
|
+
const [ baseId, quoteId ] = id.split ('_');
|
615
|
+
const base = this.safeCurrencyCode (baseId);
|
616
|
+
const quote = this.safeCurrencyCode (quoteId);
|
617
|
+
const settleId = this.safeValue (market, 'marginCurrencyName');
|
618
|
+
const settle = this.safeCurrencyCode (settleId);
|
619
|
+
const spot = settle === undefined;
|
620
|
+
const swap = this.safeValue (market, 'futures', false);
|
621
|
+
const linear = swap ? true : undefined;
|
622
|
+
let active = true;
|
623
|
+
let symbol = base + '/' + quote;
|
624
|
+
const amountPrecisionString = this.safeString2 (market, 'amountScale', 'amountDecimal');
|
625
|
+
const pricePrecisionString = this.safeString2 (market, 'priceScale', 'priceDecimal');
|
626
|
+
if (swap) {
|
627
|
+
const status = this.safeString (market, 'status');
|
628
|
+
active = (status === '1');
|
629
|
+
symbol = base + '/' + quote + ':' + settle;
|
630
|
+
}
|
631
|
+
result.push ({
|
632
|
+
'id': id,
|
633
|
+
'symbol': symbol,
|
634
|
+
'base': base,
|
635
|
+
'quote': quote,
|
636
|
+
'settle': settle,
|
637
|
+
'baseId': baseId,
|
638
|
+
'quoteId': quoteId,
|
639
|
+
'settleId': settleId,
|
640
|
+
'type': swap ? 'swap' : 'spot',
|
641
|
+
'spot': spot,
|
642
|
+
'margin': false,
|
643
|
+
'swap': swap,
|
644
|
+
'future': false,
|
645
|
+
'option': false,
|
646
|
+
'active': active,
|
647
|
+
'contract': swap,
|
648
|
+
'linear': linear,
|
649
|
+
'inverse': swap ? !linear : undefined,
|
650
|
+
'contractSize': undefined,
|
651
|
+
'expiry': undefined,
|
652
|
+
'expiryDatetime': undefined,
|
653
|
+
'strike': undefined,
|
654
|
+
'optionType': undefined,
|
655
|
+
'precision': {
|
656
|
+
'amount': parseInt (amountPrecisionString),
|
657
|
+
'price': parseInt (pricePrecisionString),
|
658
|
+
},
|
659
|
+
'limits': {
|
660
|
+
'leverage': {
|
661
|
+
'min': undefined,
|
662
|
+
'max': this.safeNumber (market, 'maxLeverage'),
|
663
|
+
},
|
664
|
+
'amount': {
|
665
|
+
'min': this.safeNumber (market, 'minAmount'),
|
666
|
+
'max': this.safeNumber (market, 'maxAmount'),
|
667
|
+
},
|
668
|
+
'price': {
|
669
|
+
'min': undefined,
|
670
|
+
'max': undefined,
|
671
|
+
},
|
672
|
+
'cost': {
|
673
|
+
'min': this.safeNumber2 (market, 'minSize', 'minTradeMoney'),
|
674
|
+
'max': this.safeNumber (market, 'maxTradeMoney'),
|
675
|
+
},
|
676
|
+
},
|
677
|
+
'info': market,
|
678
|
+
});
|
679
|
+
}
|
680
|
+
return result;
|
681
|
+
}
|
682
|
+
|
683
|
+
async fetchCurrencies (params = {}) {
|
684
|
+
const response = await this.spotV1PublicGetGetFeeInfo (params);
|
685
|
+
//
|
686
|
+
// {
|
687
|
+
// "code":1000,
|
688
|
+
// "message":"success",
|
689
|
+
// "result":{
|
690
|
+
// "USDT":[
|
691
|
+
// {
|
692
|
+
// "chainName":"TRC20",
|
693
|
+
// "canWithdraw":true,
|
694
|
+
// "fee":1.0,
|
695
|
+
// "mainChainName":"TRX",
|
696
|
+
// "canDeposit":true
|
697
|
+
// },
|
698
|
+
// {
|
699
|
+
// "chainName":"OMNI",
|
700
|
+
// "canWithdraw":true,
|
701
|
+
// "fee":5.0,
|
702
|
+
// "mainChainName":"BTC",
|
703
|
+
// "canDeposit":true
|
704
|
+
// },
|
705
|
+
// {
|
706
|
+
// "chainName":"ERC20",
|
707
|
+
// "canWithdraw":true,
|
708
|
+
// "fee":15.0,
|
709
|
+
// "mainChainName":"ETH",
|
710
|
+
// "canDeposit":true
|
711
|
+
// }
|
712
|
+
// ],
|
713
|
+
// }
|
714
|
+
// }
|
715
|
+
//
|
716
|
+
const currencies = this.safeValue (response, 'result', {});
|
717
|
+
const ids = Object.keys (currencies);
|
718
|
+
const result = {};
|
719
|
+
for (let i = 0; i < ids.length; i++) {
|
720
|
+
const id = ids[i];
|
721
|
+
const currency = currencies[id];
|
722
|
+
const code = this.safeCurrencyCode (id);
|
723
|
+
const precision = undefined;
|
724
|
+
let isWithdrawEnabled = true;
|
725
|
+
let isDepositEnabled = true;
|
726
|
+
const fees = {};
|
727
|
+
for (let j = 0; j < currency.length; j++) {
|
728
|
+
const networkItem = currency[j];
|
729
|
+
const network = this.safeString (networkItem, 'chainName');
|
730
|
+
// const name = this.safeString (networkItem, 'name');
|
731
|
+
const withdrawFee = this.safeNumber (networkItem, 'fee');
|
732
|
+
const depositEnable = this.safeValue (networkItem, 'canDeposit');
|
733
|
+
const withdrawEnable = this.safeValue (networkItem, 'canWithdraw');
|
734
|
+
isDepositEnabled = isDepositEnabled || depositEnable;
|
735
|
+
isWithdrawEnabled = isWithdrawEnabled || withdrawEnable;
|
736
|
+
fees[network] = withdrawFee;
|
737
|
+
}
|
738
|
+
const active = (isWithdrawEnabled && isDepositEnabled);
|
739
|
+
result[code] = {
|
740
|
+
'id': id,
|
741
|
+
'name': undefined,
|
742
|
+
'code': code,
|
743
|
+
'precision': precision,
|
744
|
+
'info': currency,
|
745
|
+
'active': active,
|
746
|
+
'deposit': isDepositEnabled,
|
747
|
+
'withdraw': isWithdrawEnabled,
|
748
|
+
'fee': undefined,
|
749
|
+
'fees': fees,
|
750
|
+
'limits': this.limits,
|
751
|
+
};
|
752
|
+
}
|
753
|
+
return result;
|
754
|
+
}
|
755
|
+
|
756
|
+
parseBalance (response) {
|
757
|
+
const balances = this.safeValue (response['result'], 'coins');
|
758
|
+
const result = {
|
759
|
+
'info': response,
|
760
|
+
};
|
761
|
+
for (let i = 0; i < balances.length; i++) {
|
762
|
+
const balance = balances[i];
|
763
|
+
// { enName: "BTC",
|
764
|
+
// freez: "0.00000000",
|
765
|
+
// unitDecimal: 8, // always 8
|
766
|
+
// cnName: "BTC",
|
767
|
+
// isCanRecharge: true, // TODO: should use this
|
768
|
+
// unitTag: "฿",
|
769
|
+
// isCanWithdraw: true, // TODO: should use this
|
770
|
+
// available: "0.00000000",
|
771
|
+
// key: "btc" }
|
772
|
+
const account = this.account ();
|
773
|
+
const currencyId = this.safeString (balance, 'key');
|
774
|
+
const code = this.safeCurrencyCode (currencyId);
|
775
|
+
account['free'] = this.safeString (balance, 'available');
|
776
|
+
account['used'] = this.safeString (balance, 'freez');
|
777
|
+
result[code] = account;
|
778
|
+
}
|
779
|
+
return this.safeBalance (result);
|
780
|
+
}
|
781
|
+
|
782
|
+
parseSwapBalance (response) {
|
783
|
+
const result = {
|
784
|
+
'info': response,
|
785
|
+
};
|
786
|
+
const data = this.safeValue (response, 'data', {});
|
787
|
+
for (let i = 0; i < data.length; i++) {
|
788
|
+
const balance = data[i];
|
789
|
+
//
|
790
|
+
// {
|
791
|
+
// "userId": "6896693805014120448",
|
792
|
+
// "currencyId": "6",
|
793
|
+
// "currencyName": "usdt",
|
794
|
+
// "amount": "30.56585118",
|
795
|
+
// "freezeAmount": "0",
|
796
|
+
// "contractType": 1,
|
797
|
+
// "id": "6899113714763638819",
|
798
|
+
// "createTime": "1644876888934",
|
799
|
+
// "modifyTime": "1645787446037",
|
800
|
+
// "accountBalance": "30.56585118",
|
801
|
+
// "allMargin": "0",
|
802
|
+
// "allowTransferOutAmount": "30.56585118"
|
803
|
+
// },
|
804
|
+
//
|
805
|
+
const code = this.safeCurrencyCode (this.safeString (balance, 'currencyName'));
|
806
|
+
const account = this.account ();
|
807
|
+
account['total'] = this.safeString (balance, 'accountBalance');
|
808
|
+
account['free'] = this.safeString (balance, 'allowTransferOutAmount');
|
809
|
+
account['used'] = this.safeString (balance, 'freezeAmount');
|
810
|
+
result[code] = account;
|
811
|
+
}
|
812
|
+
return this.safeBalance (result);
|
813
|
+
}
|
814
|
+
|
815
|
+
parseMarginBalance (response, marginType) {
|
816
|
+
const result = {
|
817
|
+
'info': response,
|
818
|
+
};
|
819
|
+
let levers = undefined;
|
820
|
+
if (marginType === 'isolated') {
|
821
|
+
const message = this.safeValue (response, 'message', {});
|
822
|
+
const data = this.safeValue (message, 'datas', {});
|
823
|
+
levers = this.safeValue (data, 'levers', []);
|
824
|
+
} else {
|
825
|
+
const crossResponse = this.safeValue (response, 'result', {});
|
826
|
+
levers = this.safeValue (crossResponse, 'list', []);
|
827
|
+
}
|
828
|
+
for (let i = 0; i < levers.length; i++) {
|
829
|
+
const balance = levers[i];
|
830
|
+
//
|
831
|
+
// Isolated Margin
|
832
|
+
//
|
833
|
+
// {
|
834
|
+
// "cNetUSD": "0.00",
|
835
|
+
// "repayLeverShow": "-",
|
836
|
+
// "cCanLoanIn": "0.002115400000000",
|
837
|
+
// "fNetCNY": "147.76081161",
|
838
|
+
// "fLoanIn": "0.00",
|
839
|
+
// "repayLevel": 0,
|
840
|
+
// "level": 1,
|
841
|
+
// "netConvertCNY": "147.760811613032",
|
842
|
+
// "cFreeze": "0.00",
|
843
|
+
// "cUnitTag": "BTC",
|
844
|
+
// "version": 1646783178609,
|
845
|
+
// "cAvailableUSD": "0.00",
|
846
|
+
// "cNetCNY": "0.00",
|
847
|
+
// "riskRate": "-",
|
848
|
+
// "fAvailableUSD": "20.49273433",
|
849
|
+
// "fNetUSD": "20.49273432",
|
850
|
+
// "cShowName": "BTC",
|
851
|
+
// "leverMultiple": "5.00",
|
852
|
+
// "couldTransferOutFiat": "20.49273433",
|
853
|
+
// "noticeLine": "1.13",
|
854
|
+
// "fFreeze": "0.00",
|
855
|
+
// "cUnitDecimal": 8,
|
856
|
+
// "fCanLoanIn": "81.970937320000000",
|
857
|
+
// "cAvailable": "0.00",
|
858
|
+
// "repayLock": false,
|
859
|
+
// "status": 1,
|
860
|
+
// "forbidType": 0,
|
861
|
+
// "totalConvertCNY": "147.760811613032",
|
862
|
+
// "cAvailableCNY": "0.00",
|
863
|
+
// "unwindPrice": "0.00",
|
864
|
+
// "fOverdraft": "0.00",
|
865
|
+
// "fShowName": "USDT",
|
866
|
+
// "statusShow": "%E6%AD%A3%E5%B8%B8",
|
867
|
+
// "cOverdraft": "0.00",
|
868
|
+
// "netConvertUSD": "20.49273433",
|
869
|
+
// "cNetBtc": "0.00",
|
870
|
+
// "loanInConvertCNY": "0.00",
|
871
|
+
// "fAvailableCNY": "147.760811613032",
|
872
|
+
// "key": "btcusdt",
|
873
|
+
// "fNetBtc": "0.0005291",
|
874
|
+
// "fUnitDecimal": 8,
|
875
|
+
// "loanInConvertUSD": "0.00",
|
876
|
+
// "showName": "BTC/USDT",
|
877
|
+
// "startLine": "1.25",
|
878
|
+
// "totalConvertUSD": "20.49273433",
|
879
|
+
// "couldTransferOutCoin": "0.00",
|
880
|
+
// "cEnName": "BTC",
|
881
|
+
// "leverMultipleInterest": "3.00",
|
882
|
+
// "fAvailable": "20.49273433",
|
883
|
+
// "fEnName": "USDT",
|
884
|
+
// "forceRepayLine": "1.08",
|
885
|
+
// "cLoanIn": "0.00"
|
886
|
+
// }
|
887
|
+
//
|
888
|
+
// Cross Margin
|
889
|
+
//
|
890
|
+
// [
|
891
|
+
// {
|
892
|
+
// "fundType": 2,
|
893
|
+
// "loanIn": 0,
|
894
|
+
// "amount": 0,
|
895
|
+
// "freeze": 0,
|
896
|
+
// "overdraft": 0,
|
897
|
+
// "key": "BTC",
|
898
|
+
// "canTransferOut": 0
|
899
|
+
// },
|
900
|
+
// ],
|
901
|
+
//
|
902
|
+
const account = this.account ();
|
903
|
+
if (marginType === 'isolated') {
|
904
|
+
const code = this.safeCurrencyCode (this.safeString (balance, 'fShowName'));
|
905
|
+
account['total'] = this.safeString (balance, 'fAvailableUSD'); // total amount in USD
|
906
|
+
account['free'] = this.safeString (balance, 'couldTransferOutFiat');
|
907
|
+
account['used'] = this.safeString (balance, 'fFreeze');
|
908
|
+
result[code] = account;
|
909
|
+
} else {
|
910
|
+
const code = this.safeCurrencyCode (this.safeString (balance, 'key'));
|
911
|
+
account['total'] = this.safeString (balance, 'amount');
|
912
|
+
account['free'] = this.safeString (balance, 'canTransferOut');
|
913
|
+
account['used'] = this.safeString (balance, 'freeze');
|
914
|
+
result[code] = account;
|
915
|
+
}
|
916
|
+
}
|
917
|
+
return this.safeBalance (result);
|
918
|
+
}
|
919
|
+
|
920
|
+
async fetchBalance (params = {}) {
|
921
|
+
await this.loadMarkets ();
|
922
|
+
const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchBalance', undefined, params);
|
923
|
+
const margin = (marketType === 'margin');
|
924
|
+
const swap = (marketType === 'swap');
|
925
|
+
let marginMethod = undefined;
|
926
|
+
const defaultMargin = margin ? 'isolated' : 'cross';
|
927
|
+
const marginType = this.safeString2 (this.options, 'defaultMarginType', 'marginType', defaultMargin);
|
928
|
+
if (marginType === 'isolated') {
|
929
|
+
marginMethod = 'spotV1PrivateGetGetLeverAssetsInfo';
|
930
|
+
} else if (marginType === 'cross') {
|
931
|
+
marginMethod = 'spotV1PrivateGetGetCrossAssets';
|
932
|
+
}
|
933
|
+
const method = this.getSupportedMapping (marketType, {
|
934
|
+
'spot': 'spotV1PrivateGetGetAccountInfo',
|
935
|
+
'swap': 'contractV2PrivateGetFundBalance',
|
936
|
+
'margin': marginMethod,
|
937
|
+
});
|
938
|
+
const request = {
|
939
|
+
// 'futuresAccountType': 1, // SWAP
|
940
|
+
// 'currencyId': currency['id'], // SWAP
|
941
|
+
// 'currencyName': 'usdt', // SWAP
|
942
|
+
};
|
943
|
+
if (swap) {
|
944
|
+
request['futuresAccountType'] = 1;
|
945
|
+
}
|
946
|
+
const response = await this[method] (this.extend (request, query));
|
947
|
+
//
|
948
|
+
// Spot
|
949
|
+
//
|
950
|
+
// {
|
951
|
+
// "result": {
|
952
|
+
// "coins": [
|
953
|
+
// {
|
954
|
+
// "isCanWithdraw": "true",
|
955
|
+
// "canLoan": false,
|
956
|
+
// "fundstype": 51,
|
957
|
+
// "showName": "ZB",
|
958
|
+
// "isCanRecharge": "true",
|
959
|
+
// "cnName": "ZB",
|
960
|
+
// "enName": "ZB",
|
961
|
+
// "available": "0",
|
962
|
+
// "freez": "0",
|
963
|
+
// "unitTag": "ZB",
|
964
|
+
// "key": "zb",
|
965
|
+
// "unitDecimal": 8
|
966
|
+
// },
|
967
|
+
// ],
|
968
|
+
// "version": 1645856691340,
|
969
|
+
// "base": {
|
970
|
+
// "auth_google_enabled": true,
|
971
|
+
// "auth_mobile_enabled": false,
|
972
|
+
// "trade_password_enabled": true,
|
973
|
+
// "username": "blank@gmail.com"
|
974
|
+
// }
|
975
|
+
// },
|
976
|
+
// "leverPerm": true,
|
977
|
+
// "otcPerm": false,
|
978
|
+
// "assetPerm": true,
|
979
|
+
// "moneyPerm": true,
|
980
|
+
// "subUserPerm": true,
|
981
|
+
// "entrustPerm": true
|
982
|
+
// }
|
983
|
+
//
|
984
|
+
// Swap
|
985
|
+
//
|
986
|
+
// {
|
987
|
+
// "code": 10000,
|
988
|
+
// "data": [
|
989
|
+
// {
|
990
|
+
// "userId": "6896693805014120448",
|
991
|
+
// "currencyId": "6",
|
992
|
+
// "currencyName": "usdt",
|
993
|
+
// "amount": "30.56585118",
|
994
|
+
// "freezeAmount": "0",
|
995
|
+
// "contractType": 1,
|
996
|
+
// "id": "6899113714763638819",
|
997
|
+
// "createTime": "1644876888934",
|
998
|
+
// "modifyTime": "1645787446037",
|
999
|
+
// "accountBalance": "30.56585118",
|
1000
|
+
// "allMargin": "0",
|
1001
|
+
// "allowTransferOutAmount": "30.56585118"
|
1002
|
+
// },
|
1003
|
+
// ],
|
1004
|
+
// "desc": "操作成功"
|
1005
|
+
// }
|
1006
|
+
//
|
1007
|
+
// Isolated Margin
|
1008
|
+
//
|
1009
|
+
// {
|
1010
|
+
// "code": 1000,
|
1011
|
+
// "message": {
|
1012
|
+
// "des": "success",
|
1013
|
+
// "isSuc": true,
|
1014
|
+
// "datas": {
|
1015
|
+
// "leverPerm": true,
|
1016
|
+
// "levers": [
|
1017
|
+
// {
|
1018
|
+
// "cNetUSD": "0.00",
|
1019
|
+
// "repayLeverShow": "-",
|
1020
|
+
// "cCanLoanIn": "0.002115400000000",
|
1021
|
+
// "fNetCNY": "147.76081161",
|
1022
|
+
// "fLoanIn": "0.00",
|
1023
|
+
// "repayLevel": 0,
|
1024
|
+
// "level": 1,
|
1025
|
+
// "netConvertCNY": "147.760811613032",
|
1026
|
+
// "cFreeze": "0.00",
|
1027
|
+
// "cUnitTag": "BTC",
|
1028
|
+
// "version": 1646783178609,
|
1029
|
+
// "cAvailableUSD": "0.00",
|
1030
|
+
// "cNetCNY": "0.00",
|
1031
|
+
// "riskRate": "-",
|
1032
|
+
// "fAvailableUSD": "20.49273433",
|
1033
|
+
// "fNetUSD": "20.49273432",
|
1034
|
+
// "cShowName": "BTC",
|
1035
|
+
// "leverMultiple": "5.00",
|
1036
|
+
// "couldTransferOutFiat": "20.49273433",
|
1037
|
+
// "noticeLine": "1.13",
|
1038
|
+
// "fFreeze": "0.00",
|
1039
|
+
// "cUnitDecimal": 8,
|
1040
|
+
// "fCanLoanIn": "81.970937320000000",
|
1041
|
+
// "cAvailable": "0.00",
|
1042
|
+
// "repayLock": false,
|
1043
|
+
// "status": 1,
|
1044
|
+
// "forbidType": 0,
|
1045
|
+
// "totalConvertCNY": "147.760811613032",
|
1046
|
+
// "cAvailableCNY": "0.00",
|
1047
|
+
// "unwindPrice": "0.00",
|
1048
|
+
// "fOverdraft": "0.00",
|
1049
|
+
// "fShowName": "USDT",
|
1050
|
+
// "statusShow": "%E6%AD%A3%E5%B8%B8",
|
1051
|
+
// "cOverdraft": "0.00",
|
1052
|
+
// "netConvertUSD": "20.49273433",
|
1053
|
+
// "cNetBtc": "0.00",
|
1054
|
+
// "loanInConvertCNY": "0.00",
|
1055
|
+
// "fAvailableCNY": "147.760811613032",
|
1056
|
+
// "key": "btcusdt",
|
1057
|
+
// "fNetBtc": "0.0005291",
|
1058
|
+
// "fUnitDecimal": 8,
|
1059
|
+
// "loanInConvertUSD": "0.00",
|
1060
|
+
// "showName": "BTC/USDT",
|
1061
|
+
// "startLine": "1.25",
|
1062
|
+
// "totalConvertUSD": "20.49273433",
|
1063
|
+
// "couldTransferOutCoin": "0.00",
|
1064
|
+
// "cEnName": "BTC",
|
1065
|
+
// "leverMultipleInterest": "3.00",
|
1066
|
+
// "fAvailable": "20.49273433",
|
1067
|
+
// "fEnName": "USDT",
|
1068
|
+
// "forceRepayLine": "1.08",
|
1069
|
+
// "cLoanIn": "0.00"
|
1070
|
+
// }
|
1071
|
+
// ]
|
1072
|
+
// }
|
1073
|
+
// }
|
1074
|
+
// }
|
1075
|
+
//
|
1076
|
+
// Cross Margin
|
1077
|
+
//
|
1078
|
+
// {
|
1079
|
+
// "code": 1000,
|
1080
|
+
// "message": "操作成功",
|
1081
|
+
// "result": {
|
1082
|
+
// "loanIn": 0,
|
1083
|
+
// "total": 71.167,
|
1084
|
+
// "riskRate": "-",
|
1085
|
+
// "list" :[
|
1086
|
+
// {
|
1087
|
+
// "fundType": 2,
|
1088
|
+
// "loanIn": 0,
|
1089
|
+
// "amount": 0,
|
1090
|
+
// "freeze": 0,
|
1091
|
+
// "overdraft": 0,
|
1092
|
+
// "key": "BTC",
|
1093
|
+
// "canTransferOut": 0
|
1094
|
+
// },
|
1095
|
+
// ],
|
1096
|
+
// "net": 71.167
|
1097
|
+
// }
|
1098
|
+
// }
|
1099
|
+
//
|
1100
|
+
// todo: use this somehow
|
1101
|
+
// let permissions = response['result']['base'];
|
1102
|
+
if (swap) {
|
1103
|
+
return this.parseSwapBalance (response);
|
1104
|
+
} else if (margin) {
|
1105
|
+
return this.parseMarginBalance (response, marginType);
|
1106
|
+
} else {
|
1107
|
+
return this.parseBalance (response);
|
1108
|
+
}
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
parseDepositAddress (depositAddress, currency = undefined) {
|
1112
|
+
//
|
1113
|
+
// fetchDepositAddress
|
1114
|
+
//
|
1115
|
+
// {
|
1116
|
+
// "key": "0x0af7f36b8f09410f3df62c81e5846da673d4d9a9"
|
1117
|
+
// }
|
1118
|
+
//
|
1119
|
+
// fetchDepositAddresses
|
1120
|
+
//
|
1121
|
+
// {
|
1122
|
+
// "blockChain": "btc",
|
1123
|
+
// "isUseMemo": false,
|
1124
|
+
// "address": "1LL5ati6pXHZnTGzHSA3rWdqi4mGGXudwM",
|
1125
|
+
// "canWithdraw": true,
|
1126
|
+
// "canDeposit": true
|
1127
|
+
// }
|
1128
|
+
// {
|
1129
|
+
// "blockChain": "bts",
|
1130
|
+
// "isUseMemo": true,
|
1131
|
+
// "account": "btstest",
|
1132
|
+
// "memo": "123",
|
1133
|
+
// "canWithdraw": true,
|
1134
|
+
// "canDeposit": true
|
1135
|
+
// }
|
1136
|
+
//
|
1137
|
+
let address = this.safeString2 (depositAddress, 'key', 'address');
|
1138
|
+
let tag = undefined;
|
1139
|
+
const memo = this.safeString (depositAddress, 'memo');
|
1140
|
+
if (memo !== undefined) {
|
1141
|
+
tag = memo;
|
1142
|
+
} else if (address.indexOf ('_') >= 0) {
|
1143
|
+
const parts = address.split ('_');
|
1144
|
+
address = parts[0]; // WARNING: MAY BE tag_address INSTEAD OF address_tag FOR SOME CURRENCIES!!
|
1145
|
+
tag = parts[1];
|
1146
|
+
}
|
1147
|
+
const currencyId = this.safeString (depositAddress, 'blockChain');
|
1148
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
1149
|
+
return {
|
1150
|
+
'currency': code,
|
1151
|
+
'address': address,
|
1152
|
+
'tag': tag,
|
1153
|
+
'network': undefined,
|
1154
|
+
'info': depositAddress,
|
1155
|
+
};
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
async fetchDepositAddresses (codes = undefined, params = {}) {
|
1159
|
+
await this.loadMarkets ();
|
1160
|
+
const response = await this.spotV1PrivateGetGetPayinAddress (params);
|
1161
|
+
//
|
1162
|
+
// {
|
1163
|
+
// "code": 1000,
|
1164
|
+
// "message": {
|
1165
|
+
// "des": "success",
|
1166
|
+
// "isSuc": true,
|
1167
|
+
// "datas": [
|
1168
|
+
// {
|
1169
|
+
// "blockChain": "btc",
|
1170
|
+
// "isUseMemo": false,
|
1171
|
+
// "address": "1LL5ati6pXHZnTGzHSA3rWdqi4mGGXudwM",
|
1172
|
+
// "canWithdraw": true,
|
1173
|
+
// "canDeposit": true
|
1174
|
+
// },
|
1175
|
+
// {
|
1176
|
+
// "blockChain": "bts",
|
1177
|
+
// "isUseMemo": true,
|
1178
|
+
// "account": "btstest",
|
1179
|
+
// "memo": "123",
|
1180
|
+
// "canWithdraw": true,
|
1181
|
+
// "canDeposit": true
|
1182
|
+
// },
|
1183
|
+
// ]
|
1184
|
+
// }
|
1185
|
+
// }
|
1186
|
+
//
|
1187
|
+
const message = this.safeValue (response, 'message', {});
|
1188
|
+
const datas = this.safeValue (message, 'datas', []);
|
1189
|
+
return this.parseDepositAddresses (datas, codes);
|
1190
|
+
}
|
1191
|
+
|
1192
|
+
async fetchDepositAddress (code, params = {}) {
|
1193
|
+
await this.loadMarkets ();
|
1194
|
+
const currency = this.currency (code);
|
1195
|
+
const request = {
|
1196
|
+
'currency': currency['id'],
|
1197
|
+
};
|
1198
|
+
const response = await this.spotV1PrivateGetGetUserAddress (this.extend (request, params));
|
1199
|
+
//
|
1200
|
+
// {
|
1201
|
+
// "code": 1000,
|
1202
|
+
// "message": {
|
1203
|
+
// "des": "success",
|
1204
|
+
// "isSuc": true,
|
1205
|
+
// "datas": {
|
1206
|
+
// "key": "0x0af7f36b8f09410f3df62c81e5846da673d4d9a9"
|
1207
|
+
// }
|
1208
|
+
// }
|
1209
|
+
// }
|
1210
|
+
//
|
1211
|
+
const message = this.safeValue (response, 'message', {});
|
1212
|
+
const datas = this.safeValue (message, 'datas', {});
|
1213
|
+
return this.parseDepositAddress (datas, currency);
|
1214
|
+
}
|
1215
|
+
|
1216
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
1217
|
+
await this.loadMarkets ();
|
1218
|
+
const market = this.market (symbol);
|
1219
|
+
const request = {
|
1220
|
+
// 'market': market['id'], // only applicable to SPOT
|
1221
|
+
// 'symbol': market['id'], // only applicable to SWAP
|
1222
|
+
// 'size': limit, // 1-50 applicable to SPOT and SWAP
|
1223
|
+
// 'merge': 5.0, // float default depth only applicable to SPOT
|
1224
|
+
// 'scale': 5, // int accuracy, only applicable to SWAP
|
1225
|
+
};
|
1226
|
+
const marketIdField = market['swap'] ? 'symbol' : 'market';
|
1227
|
+
request[marketIdField] = market['id'];
|
1228
|
+
const method = this.getSupportedMapping (market['type'], {
|
1229
|
+
'spot': 'spotV1PublicGetDepth',
|
1230
|
+
'swap': 'contractV1PublicGetDepth',
|
1231
|
+
});
|
1232
|
+
if (limit !== undefined) {
|
1233
|
+
request['size'] = limit;
|
1234
|
+
}
|
1235
|
+
const response = await this[method] (this.extend (request, params));
|
1236
|
+
//
|
1237
|
+
// Spot
|
1238
|
+
//
|
1239
|
+
// {
|
1240
|
+
// "asks":[
|
1241
|
+
// [35000.0,0.2741],
|
1242
|
+
// [34949.0,0.0173],
|
1243
|
+
// [34900.0,0.5004],
|
1244
|
+
// ],
|
1245
|
+
// "bids":[
|
1246
|
+
// [34119.32,0.0030],
|
1247
|
+
// [34107.83,0.1500],
|
1248
|
+
// [34104.42,0.1500],
|
1249
|
+
// ],
|
1250
|
+
// "timestamp":1624536510
|
1251
|
+
// }
|
1252
|
+
//
|
1253
|
+
// Swap
|
1254
|
+
//
|
1255
|
+
// {
|
1256
|
+
// "code": 10000,
|
1257
|
+
// "desc": "操作成功",
|
1258
|
+
// "data": {
|
1259
|
+
// "asks": [
|
1260
|
+
// [43416.6,0.02],
|
1261
|
+
// [43418.25,0.04],
|
1262
|
+
// [43425.82,0.02]
|
1263
|
+
// ],
|
1264
|
+
// "bids": [
|
1265
|
+
// [43414.61,0.1],
|
1266
|
+
// [43414.18,0.04],
|
1267
|
+
// [43413.03,0.05]
|
1268
|
+
// ],
|
1269
|
+
// "time": 1645087743071
|
1270
|
+
// }
|
1271
|
+
// }
|
1272
|
+
//
|
1273
|
+
let result = undefined;
|
1274
|
+
let timestamp = undefined;
|
1275
|
+
if (market['type'] === 'swap') {
|
1276
|
+
result = this.safeValue (response, 'data');
|
1277
|
+
timestamp = this.safeInteger (result, 'time');
|
1278
|
+
} else {
|
1279
|
+
result = response;
|
1280
|
+
timestamp = this.safeTimestamp (response, 'timestamp');
|
1281
|
+
}
|
1282
|
+
return this.parseOrderBook (result, symbol, timestamp);
|
1283
|
+
}
|
1284
|
+
|
1285
|
+
async fetchTickers (symbols = undefined, params = {}) {
|
1286
|
+
await this.loadMarkets ();
|
1287
|
+
const response = await this.spotV1PublicGetAllTicker (params);
|
1288
|
+
const result = {};
|
1289
|
+
const marketsByIdWithoutUnderscore = {};
|
1290
|
+
const marketIds = Object.keys (this.markets_by_id);
|
1291
|
+
for (let i = 0; i < marketIds.length; i++) {
|
1292
|
+
const tickerId = marketIds[i].replace ('_', '');
|
1293
|
+
marketsByIdWithoutUnderscore[tickerId] = this.markets_by_id[marketIds[i]];
|
1294
|
+
}
|
1295
|
+
const ids = Object.keys (response);
|
1296
|
+
for (let i = 0; i < ids.length; i++) {
|
1297
|
+
const market = this.safeValue (marketsByIdWithoutUnderscore, ids[i]);
|
1298
|
+
if (market !== undefined) {
|
1299
|
+
const symbol = market['symbol'];
|
1300
|
+
const ticker = this.safeValue (response, ids[i]);
|
1301
|
+
if (ticker !== undefined) {
|
1302
|
+
result[symbol] = this.parseTicker (ticker, market);
|
1303
|
+
}
|
1304
|
+
}
|
1305
|
+
}
|
1306
|
+
return this.filterByArray (result, 'symbol', symbols);
|
1307
|
+
}
|
1308
|
+
|
1309
|
+
async fetchTicker (symbol, params = {}) {
|
1310
|
+
await this.loadMarkets ();
|
1311
|
+
const market = this.market (symbol);
|
1312
|
+
const request = {
|
1313
|
+
// 'market': market['id'], // only applicable to SPOT
|
1314
|
+
// 'symbol': market['id'], // only applicable to SWAP
|
1315
|
+
};
|
1316
|
+
const marketIdField = market['swap'] ? 'symbol' : 'market';
|
1317
|
+
request[marketIdField] = market['id'];
|
1318
|
+
const method = this.getSupportedMapping (market['type'], {
|
1319
|
+
'spot': 'spotV1PublicGetTicker',
|
1320
|
+
'swap': 'contractV1PublicGetTicker',
|
1321
|
+
});
|
1322
|
+
const response = await this[method] (this.extend (request, params));
|
1323
|
+
//
|
1324
|
+
// Spot
|
1325
|
+
//
|
1326
|
+
// {
|
1327
|
+
// "date":"1624399623587",
|
1328
|
+
// "ticker":{
|
1329
|
+
// "high":"33298.38",
|
1330
|
+
// "vol":"56152.9012",
|
1331
|
+
// "last":"32578.55",
|
1332
|
+
// "low":"28808.19",
|
1333
|
+
// "buy":"32572.68",
|
1334
|
+
// "sell":"32615.37",
|
1335
|
+
// "turnover":"1764201303.6100",
|
1336
|
+
// "open":"31664.85",
|
1337
|
+
// "riseRate":"2.89"
|
1338
|
+
// }
|
1339
|
+
// }
|
1340
|
+
//
|
1341
|
+
// Swap
|
1342
|
+
//
|
1343
|
+
// {
|
1344
|
+
// "code": 10000,
|
1345
|
+
// "desc": "操作成功",
|
1346
|
+
// "data": {
|
1347
|
+
// "BTC_USDT": [44053.47,44357.77,42911.54,43297.79,53471.264,-1.72,1645093002,302201.255084]
|
1348
|
+
// }
|
1349
|
+
// }
|
1350
|
+
//
|
1351
|
+
let ticker = undefined;
|
1352
|
+
if (market['type'] === 'swap') {
|
1353
|
+
ticker = {};
|
1354
|
+
const data = this.safeValue (response, 'data');
|
1355
|
+
const values = this.safeValue (data, market['id']);
|
1356
|
+
for (let i = 0; i < values.length; i++) {
|
1357
|
+
ticker['open'] = this.safeValue (values, 0);
|
1358
|
+
ticker['high'] = this.safeValue (values, 1);
|
1359
|
+
ticker['low'] = this.safeValue (values, 2);
|
1360
|
+
ticker['last'] = this.safeValue (values, 3);
|
1361
|
+
ticker['vol'] = this.safeValue (values, 4);
|
1362
|
+
ticker['riseRate'] = this.safeValue (values, 5);
|
1363
|
+
}
|
1364
|
+
} else {
|
1365
|
+
ticker = this.safeValue (response, 'ticker', {});
|
1366
|
+
ticker['date'] = this.safeValue (response, 'date');
|
1367
|
+
}
|
1368
|
+
return this.parseTicker (ticker, market);
|
1369
|
+
}
|
1370
|
+
|
1371
|
+
parseTicker (ticker, market = undefined) {
|
1372
|
+
//
|
1373
|
+
// Spot
|
1374
|
+
//
|
1375
|
+
// {
|
1376
|
+
// "date":"1624399623587", // injected from outside
|
1377
|
+
// "high":"33298.38",
|
1378
|
+
// "vol":"56152.9012",
|
1379
|
+
// "last":"32578.55",
|
1380
|
+
// "low":"28808.19",
|
1381
|
+
// "buy":"32572.68",
|
1382
|
+
// "sell":"32615.37",
|
1383
|
+
// "turnover":"1764201303.6100",
|
1384
|
+
// "open":"31664.85",
|
1385
|
+
// "riseRate":"2.89"
|
1386
|
+
// }
|
1387
|
+
//
|
1388
|
+
// Swap
|
1389
|
+
//
|
1390
|
+
// {
|
1391
|
+
// open: 44083.82,
|
1392
|
+
// high: 44357.77,
|
1393
|
+
// low: 42911.54,
|
1394
|
+
// last: 43097.87,
|
1395
|
+
// vol: 53451.641,
|
1396
|
+
// riseRate: -2.24
|
1397
|
+
// }
|
1398
|
+
//
|
1399
|
+
const timestamp = this.safeInteger (ticker, 'date', this.milliseconds ());
|
1400
|
+
const last = this.safeString (ticker, 'last');
|
1401
|
+
return this.safeTicker ({
|
1402
|
+
'symbol': this.safeSymbol (undefined, market),
|
1403
|
+
'timestamp': timestamp,
|
1404
|
+
'datetime': this.iso8601 (timestamp),
|
1405
|
+
'high': this.safeString (ticker, 'high'),
|
1406
|
+
'low': this.safeString (ticker, 'low'),
|
1407
|
+
'bid': this.safeString (ticker, 'buy'),
|
1408
|
+
'bidVolume': undefined,
|
1409
|
+
'ask': this.safeString (ticker, 'sell'),
|
1410
|
+
'askVolume': undefined,
|
1411
|
+
'vwap': undefined,
|
1412
|
+
'open': this.safeString (ticker, 'open'),
|
1413
|
+
'close': last,
|
1414
|
+
'last': last,
|
1415
|
+
'previousClose': undefined,
|
1416
|
+
'change': undefined,
|
1417
|
+
'percentage': undefined,
|
1418
|
+
'average': undefined,
|
1419
|
+
'baseVolume': this.safeString (ticker, 'vol'),
|
1420
|
+
'quoteVolume': undefined,
|
1421
|
+
'info': ticker,
|
1422
|
+
}, market, false);
|
1423
|
+
}
|
1424
|
+
|
1425
|
+
parseOHLCV (ohlcv, market = undefined) {
|
1426
|
+
if (market['swap']) {
|
1427
|
+
const ohlcvLength = ohlcv.length;
|
1428
|
+
if (ohlcvLength > 5) {
|
1429
|
+
return [
|
1430
|
+
this.safeTimestamp (ohlcv, 5),
|
1431
|
+
this.safeNumber (ohlcv, 0),
|
1432
|
+
this.safeNumber (ohlcv, 1),
|
1433
|
+
this.safeNumber (ohlcv, 2),
|
1434
|
+
this.safeNumber (ohlcv, 3),
|
1435
|
+
this.safeNumber (ohlcv, 4),
|
1436
|
+
];
|
1437
|
+
} else {
|
1438
|
+
return [
|
1439
|
+
this.safeTimestamp (ohlcv, 4),
|
1440
|
+
this.safeNumber (ohlcv, 0),
|
1441
|
+
this.safeNumber (ohlcv, 1),
|
1442
|
+
this.safeNumber (ohlcv, 2),
|
1443
|
+
this.safeNumber (ohlcv, 3),
|
1444
|
+
undefined,
|
1445
|
+
];
|
1446
|
+
}
|
1447
|
+
} else {
|
1448
|
+
return [
|
1449
|
+
this.safeInteger (ohlcv, 0),
|
1450
|
+
this.safeNumber (ohlcv, 1),
|
1451
|
+
this.safeNumber (ohlcv, 2),
|
1452
|
+
this.safeNumber (ohlcv, 3),
|
1453
|
+
this.safeNumber (ohlcv, 4),
|
1454
|
+
this.safeNumber (ohlcv, 5),
|
1455
|
+
];
|
1456
|
+
}
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1460
|
+
await this.loadMarkets ();
|
1461
|
+
const market = this.market (symbol);
|
1462
|
+
const swap = market['swap'];
|
1463
|
+
const spot = market['spot'];
|
1464
|
+
const options = this.safeValue (this.options, 'timeframes', {});
|
1465
|
+
const timeframes = this.safeValue (options, market['type'], {});
|
1466
|
+
const timeframeValue = this.safeString (timeframes, timeframe);
|
1467
|
+
if (timeframeValue === undefined) {
|
1468
|
+
throw new NotSupported (this.id + ' fetchOHLCV() does not support ' + timeframe + ' timeframe for ' + market['type'] + ' markets');
|
1469
|
+
}
|
1470
|
+
if (limit === undefined) {
|
1471
|
+
limit = 1000;
|
1472
|
+
}
|
1473
|
+
const request = {
|
1474
|
+
// 'market': market['id'], // spot only
|
1475
|
+
// 'symbol': market['id'], // swap only
|
1476
|
+
// 'type': timeframeValue, // spot only
|
1477
|
+
// 'period': timeframeValue, // swap only
|
1478
|
+
// 'since': since, // spot only
|
1479
|
+
// 'size': limit, // spot and swap
|
1480
|
+
};
|
1481
|
+
const marketIdField = swap ? 'symbol' : 'market';
|
1482
|
+
request[marketIdField] = market['id'];
|
1483
|
+
const periodField = swap ? 'period' : 'type';
|
1484
|
+
request[periodField] = timeframeValue;
|
1485
|
+
const price = this.safeString (params, 'price');
|
1486
|
+
params = this.omit (params, 'price');
|
1487
|
+
let method = this.getSupportedMapping (market['type'], {
|
1488
|
+
'spot': 'spotV1PublicGetKline',
|
1489
|
+
'swap': 'contractV1PublicGetKline',
|
1490
|
+
});
|
1491
|
+
if (swap) {
|
1492
|
+
if (price === 'mark') {
|
1493
|
+
method = 'contractV1PublicGetMarkKline';
|
1494
|
+
} else if (price === 'index') {
|
1495
|
+
method = 'contractV1PublicGetIndexKline';
|
1496
|
+
}
|
1497
|
+
} else if (spot) {
|
1498
|
+
if (since !== undefined) {
|
1499
|
+
request['since'] = since;
|
1500
|
+
}
|
1501
|
+
}
|
1502
|
+
if (limit !== undefined) {
|
1503
|
+
request['size'] = limit;
|
1504
|
+
}
|
1505
|
+
const response = await this[method] (this.extend (request, params));
|
1506
|
+
//
|
1507
|
+
// Spot
|
1508
|
+
//
|
1509
|
+
// {
|
1510
|
+
// "symbol": "BTC",
|
1511
|
+
// "data": [
|
1512
|
+
// [1645091400000,43183.24,43187.49,43145.92,43182.28,0.9110],
|
1513
|
+
// [1645091460000,43182.18,43183.15,43182.06,43183.15,1.4393],
|
1514
|
+
// [1645091520000,43182.11,43240.1,43182.11,43240.1,0.3802]
|
1515
|
+
// ],
|
1516
|
+
// "moneyType": "USDT"
|
1517
|
+
// }
|
1518
|
+
//
|
1519
|
+
// Swap
|
1520
|
+
//
|
1521
|
+
// {
|
1522
|
+
// "code": 10000,
|
1523
|
+
// "desc": "操作成功",
|
1524
|
+
// "data": [
|
1525
|
+
// [41433.44,41433.44,41405.88,41408.75,21.368,1646366460],
|
1526
|
+
// [41409.25,41423.74,41408.8,41423.42,9.828,1646366520],
|
1527
|
+
// [41423.96,41429.39,41369.98,41370.31,123.104,1646366580]
|
1528
|
+
// ]
|
1529
|
+
// }
|
1530
|
+
//
|
1531
|
+
// Mark
|
1532
|
+
//
|
1533
|
+
// {
|
1534
|
+
// "code": 10000,
|
1535
|
+
// "desc": "操作成功",
|
1536
|
+
// "data": [
|
1537
|
+
// [41603.39,41603.39,41591.59,41600.81,1646381760],
|
1538
|
+
// [41600.36,41605.75,41587.69,41601.97,1646381820],
|
1539
|
+
// [41601.97,41601.97,41562.62,41593.96,1646381880]
|
1540
|
+
// ]
|
1541
|
+
// }
|
1542
|
+
//
|
1543
|
+
// Index
|
1544
|
+
//
|
1545
|
+
// {
|
1546
|
+
// "code": 10000,
|
1547
|
+
// "desc": "操作成功",
|
1548
|
+
// "data": [
|
1549
|
+
// [41697.53,41722.29,41689.16,41689.16,1646381640],
|
1550
|
+
// [41690.1,41691.73,41611.61,41611.61,1646381700],
|
1551
|
+
// [41611.61,41619.49,41594.87,41594.87,1646381760]
|
1552
|
+
// ]
|
1553
|
+
// }
|
1554
|
+
//
|
1555
|
+
const data = this.safeValue (response, 'data', []);
|
1556
|
+
return this.parseOHLCVs (data, market, timeframe, since, limit);
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
async fetchMarkOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1560
|
+
const request = {
|
1561
|
+
'price': 'mark',
|
1562
|
+
};
|
1563
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
1564
|
+
}
|
1565
|
+
|
1566
|
+
async fetchIndexOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
1567
|
+
const request = {
|
1568
|
+
'price': 'index',
|
1569
|
+
};
|
1570
|
+
return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
|
1571
|
+
}
|
1572
|
+
|
1573
|
+
parseTrade (trade, market = undefined) {
|
1574
|
+
//
|
1575
|
+
// Spot
|
1576
|
+
//
|
1577
|
+
// {
|
1578
|
+
// "date":1624537391,
|
1579
|
+
// "amount":"0.0142",
|
1580
|
+
// "price":"33936.42",
|
1581
|
+
// "trade_type":"ask",
|
1582
|
+
// "type":"sell",
|
1583
|
+
// "tid":1718869018
|
1584
|
+
// }
|
1585
|
+
//
|
1586
|
+
// Swap
|
1587
|
+
//
|
1588
|
+
// {
|
1589
|
+
// "amount": "0.002",
|
1590
|
+
// "createTime": "1645787446034",
|
1591
|
+
// "feeAmount": "-0.05762699",
|
1592
|
+
// "feeCurrency": "USDT",
|
1593
|
+
// "id": "6902932868050395136",
|
1594
|
+
// "maker": false,
|
1595
|
+
// "orderId": "6902932868042006528",
|
1596
|
+
// "price": "38417.99",
|
1597
|
+
// "relizedPnl": "0.30402",
|
1598
|
+
// "side": 4,
|
1599
|
+
// "userId": "6896693805014120448"
|
1600
|
+
// },
|
1601
|
+
//
|
1602
|
+
const sideField = market['swap'] ? 'side' : 'trade_type';
|
1603
|
+
let side = this.safeString (trade, sideField);
|
1604
|
+
let takerOrMaker = undefined;
|
1605
|
+
const maker = this.safeValue (trade, 'maker');
|
1606
|
+
if (maker !== undefined) {
|
1607
|
+
takerOrMaker = maker ? 'maker' : 'taker';
|
1608
|
+
}
|
1609
|
+
if (market['spot']) {
|
1610
|
+
side = (side === 'bid') ? 'buy' : 'sell';
|
1611
|
+
} else {
|
1612
|
+
if (side === '3') {
|
1613
|
+
side = 'sell'; // close long
|
1614
|
+
} else if (side === '4') {
|
1615
|
+
side = 'buy'; // close short
|
1616
|
+
} else if (side === '1') {
|
1617
|
+
side = 'buy'; // open long
|
1618
|
+
} else if (side === '2') {
|
1619
|
+
side = 'sell'; // open short
|
1620
|
+
}
|
1621
|
+
}
|
1622
|
+
let timestamp = undefined;
|
1623
|
+
if (market['swap']) {
|
1624
|
+
timestamp = this.safeInteger (trade, 'createTime');
|
1625
|
+
} else {
|
1626
|
+
timestamp = this.safeTimestamp (trade, 'date');
|
1627
|
+
}
|
1628
|
+
const price = this.safeString (trade, 'price');
|
1629
|
+
const amount = this.safeString (trade, 'amount');
|
1630
|
+
let fee = undefined;
|
1631
|
+
const feeCostString = this.safeString (trade, 'feeAmount');
|
1632
|
+
if (feeCostString !== undefined) {
|
1633
|
+
const feeCurrencyId = this.safeString (trade, 'feeCurrency');
|
1634
|
+
fee = {
|
1635
|
+
'cost': feeCostString,
|
1636
|
+
'currency': this.safeCurrencyCode (feeCurrencyId),
|
1637
|
+
};
|
1638
|
+
}
|
1639
|
+
market = this.safeMarket (undefined, market);
|
1640
|
+
return this.safeTrade ({
|
1641
|
+
'info': trade,
|
1642
|
+
'id': this.safeString (trade, 'tid'),
|
1643
|
+
'timestamp': timestamp,
|
1644
|
+
'datetime': this.iso8601 (timestamp),
|
1645
|
+
'symbol': market['symbol'],
|
1646
|
+
'type': undefined,
|
1647
|
+
'side': side,
|
1648
|
+
'order': this.safeString (trade, 'orderId'),
|
1649
|
+
'takerOrMaker': takerOrMaker,
|
1650
|
+
'price': price,
|
1651
|
+
'amount': amount,
|
1652
|
+
'cost': undefined,
|
1653
|
+
'fee': fee,
|
1654
|
+
}, market);
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
1658
|
+
if (symbol === undefined) {
|
1659
|
+
throw new ArgumentsRequired (this.id + ' fetchTrades() requires a symbol argument');
|
1660
|
+
}
|
1661
|
+
await this.loadMarkets ();
|
1662
|
+
const market = this.market (symbol);
|
1663
|
+
const swap = market['swap'];
|
1664
|
+
const request = {
|
1665
|
+
// 'market': market['id'], // SPOT
|
1666
|
+
// 'symbol': market['id'], // SWAP
|
1667
|
+
// 'side': 1, // SWAP
|
1668
|
+
// 'dateRange': 0, // SWAP
|
1669
|
+
// 'startTime': since, // SWAP
|
1670
|
+
// 'endtime': this.milliseconds (), // SWAP
|
1671
|
+
// 'pageNum': 1, // SWAP
|
1672
|
+
// 'pageSize': limit, // SWAP default is 10
|
1673
|
+
};
|
1674
|
+
if (limit !== undefined) {
|
1675
|
+
request['pageSize'] = limit;
|
1676
|
+
}
|
1677
|
+
if (since !== undefined) {
|
1678
|
+
request['startTime'] = since;
|
1679
|
+
}
|
1680
|
+
const marketIdField = swap ? 'symbol' : 'market';
|
1681
|
+
request[marketIdField] = market['id'];
|
1682
|
+
if (swap && params['pageNum'] === undefined) {
|
1683
|
+
request['pageNum'] = 1;
|
1684
|
+
}
|
1685
|
+
const method = this.getSupportedMapping (market['type'], {
|
1686
|
+
'spot': 'spotV1PublicGetTrades',
|
1687
|
+
'swap': 'contractV2PrivateGetTradeTradeHistory',
|
1688
|
+
});
|
1689
|
+
let response = await this[method] (this.extend (request, params));
|
1690
|
+
//
|
1691
|
+
// Spot
|
1692
|
+
//
|
1693
|
+
// [
|
1694
|
+
// {"date":1624537391,"amount":"0.0142","price":"33936.42","trade_type":"ask","type":"sell","tid":1718869018},
|
1695
|
+
// {"date":1624537391,"amount":"0.0010","price":"33936.42","trade_type":"ask","type":"sell","tid":1718869020},
|
1696
|
+
// {"date":1624537391,"amount":"0.0133","price":"33936.42","trade_type":"ask","type":"sell","tid":1718869021},
|
1697
|
+
// ]
|
1698
|
+
//
|
1699
|
+
// Swap
|
1700
|
+
//
|
1701
|
+
// {
|
1702
|
+
// "code": 10000,
|
1703
|
+
// "data": {
|
1704
|
+
// "list": [
|
1705
|
+
// {
|
1706
|
+
// "amount": "0.002",
|
1707
|
+
// "createTime": "1645787446034",
|
1708
|
+
// "feeAmount": "-0.05762699",
|
1709
|
+
// "feeCurrency": "USDT",
|
1710
|
+
// "id": "6902932868050395136",
|
1711
|
+
// "maker": false,
|
1712
|
+
// "orderId": "6902932868042006528",
|
1713
|
+
// "price": "38417.99",
|
1714
|
+
// "relizedPnl": "0.30402",
|
1715
|
+
// "side": 4,
|
1716
|
+
// "userId": "6896693805014120448"
|
1717
|
+
// },
|
1718
|
+
// ],
|
1719
|
+
// "pageNum": 1,
|
1720
|
+
// "pageSize": 10
|
1721
|
+
// },
|
1722
|
+
// "desc": "操作成功"
|
1723
|
+
// }
|
1724
|
+
//
|
1725
|
+
if (swap) {
|
1726
|
+
const data = this.safeValue (response, 'data');
|
1727
|
+
response = this.safeValue (data, 'list');
|
1728
|
+
}
|
1729
|
+
return this.parseTrades (response, market, since, limit);
|
1730
|
+
}
|
1731
|
+
|
1732
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
1733
|
+
await this.loadMarkets ();
|
1734
|
+
const market = this.market (symbol);
|
1735
|
+
const swap = market['swap'];
|
1736
|
+
const spot = market['spot'];
|
1737
|
+
const timeInForce = this.safeString (params, 'timeInForce');
|
1738
|
+
const reduceOnly = this.safeValue (params, 'reduceOnly');
|
1739
|
+
const stop = this.safeValue (params, 'stop');
|
1740
|
+
const stopPrice = this.safeNumber2 (params, 'triggerPrice', 'stopPrice');
|
1741
|
+
if (type === 'market') {
|
1742
|
+
throw new InvalidOrder (this.id + ' createOrder() on ' + market['type'] + ' markets does not allow market orders');
|
1743
|
+
}
|
1744
|
+
let method = this.getSupportedMapping (market['type'], {
|
1745
|
+
'spot': 'spotV1PrivateGetOrder',
|
1746
|
+
'swap': 'contractV2PrivatePostTradeOrder',
|
1747
|
+
});
|
1748
|
+
const request = {
|
1749
|
+
'amount': this.amountToPrecision (symbol, amount),
|
1750
|
+
// 'symbol': market['id'],
|
1751
|
+
// 'acctType': 0, // Spot, Margin 0/1/2 [Spot/Isolated/Cross] Optional, Default to: 0 Spot
|
1752
|
+
// 'customerOrderId': '1f2g', // Spot, Margin
|
1753
|
+
// 'orderType': 1, // Spot, Margin order type 1/2 [PostOnly/IOC] Optional
|
1754
|
+
// 'triggerPrice': 30000.0, // Stop trigger price
|
1755
|
+
// 'algoPrice': 29000.0, // Stop order price
|
1756
|
+
// 'priceType': 1, // Stop Loss Take Profit, 1: Mark price, 2: Last price
|
1757
|
+
// 'bizType': 1, // Stop Loss Take Profit, 1: TP, 2: SL
|
1758
|
+
};
|
1759
|
+
if (stop || stopPrice) {
|
1760
|
+
method = 'contractV2PrivatePostTradeOrderAlgo';
|
1761
|
+
const orderType = this.safeInteger (params, 'orderType');
|
1762
|
+
const priceType = this.safeInteger (params, 'priceType');
|
1763
|
+
const bizType = this.safeInteger (params, 'bizType');
|
1764
|
+
const algoPrice = this.safeNumber (params, 'algoPrice');
|
1765
|
+
request['symbol'] = market['id'];
|
1766
|
+
if (side === 'sell' && reduceOnly) {
|
1767
|
+
request['side'] = 3; // close long
|
1768
|
+
} else if (side === 'buy' && reduceOnly) {
|
1769
|
+
request['side'] = 4; // close short
|
1770
|
+
} else if (side === 'buy') {
|
1771
|
+
request['side'] = 1; // open long
|
1772
|
+
} else if (side === 'sell') {
|
1773
|
+
request['side'] = 2; // open short
|
1774
|
+
} else if (side === 5) {
|
1775
|
+
request['side'] = 5; // one way position buy
|
1776
|
+
} else if (side === 6) {
|
1777
|
+
request['side'] = 6; // one way position sell
|
1778
|
+
} else if (side === 0) {
|
1779
|
+
request['side'] = 0; // one way position close only
|
1780
|
+
}
|
1781
|
+
if (type === 'trigger' || orderType === 1) {
|
1782
|
+
request['orderType'] = 1;
|
1783
|
+
} else if (type === 'stop loss' || type === 'take profit' || orderType === 2 || priceType || bizType) {
|
1784
|
+
request['orderType'] = 2;
|
1785
|
+
request['priceType'] = priceType;
|
1786
|
+
request['bizType'] = bizType;
|
1787
|
+
}
|
1788
|
+
request['triggerPrice'] = this.priceToPrecision (symbol, stopPrice);
|
1789
|
+
request['algoPrice'] = this.priceToPrecision (symbol, algoPrice);
|
1790
|
+
} else {
|
1791
|
+
if (price) {
|
1792
|
+
request['price'] = this.priceToPrecision (symbol, price);
|
1793
|
+
}
|
1794
|
+
if (spot) {
|
1795
|
+
request['tradeType'] = (side === 'buy') ? '1' : '0';
|
1796
|
+
request['currency'] = market['id'];
|
1797
|
+
if (timeInForce !== undefined) {
|
1798
|
+
if (timeInForce === 'PO') {
|
1799
|
+
request['orderType'] = 1;
|
1800
|
+
} else if (timeInForce === 'IOC') {
|
1801
|
+
request['orderType'] = 2;
|
1802
|
+
} else {
|
1803
|
+
throw new InvalidOrder (this.id + ' createOrder() on ' + market['type'] + ' markets does not allow ' + timeInForce + ' orders');
|
1804
|
+
}
|
1805
|
+
}
|
1806
|
+
} else if (swap) {
|
1807
|
+
if (side === 'sell' && reduceOnly) {
|
1808
|
+
request['side'] = 3; // close long
|
1809
|
+
} else if (side === 'buy' && reduceOnly) {
|
1810
|
+
request['side'] = 4; // close short
|
1811
|
+
} else if (side === 'buy') {
|
1812
|
+
request['side'] = 1; // open long
|
1813
|
+
} else if (side === 'sell') {
|
1814
|
+
request['side'] = 2; // open short
|
1815
|
+
}
|
1816
|
+
if (type === 'limit') {
|
1817
|
+
request['action'] = 1;
|
1818
|
+
} else if (timeInForce === 'IOC') {
|
1819
|
+
request['action'] = 3;
|
1820
|
+
} else if (timeInForce === 'PO') {
|
1821
|
+
request['action'] = 4;
|
1822
|
+
} else if (timeInForce === 'FOK') {
|
1823
|
+
request['action'] = 5;
|
1824
|
+
} else {
|
1825
|
+
request['action'] = type;
|
1826
|
+
}
|
1827
|
+
request['symbol'] = market['id'];
|
1828
|
+
request['clientOrderId'] = params['clientOrderId']; // OPTIONAL '^[a-zA-Z0-9-_]{1,36}$', // The user-defined order number
|
1829
|
+
request['extend'] = params['extend']; // OPTIONAL {"orderAlgos":[{"bizType":1,"priceType":1,"triggerPrice":"70000"},{"bizType":2,"priceType":1,"triggerPrice":"40000"}]}
|
1830
|
+
}
|
1831
|
+
}
|
1832
|
+
const query = this.omit (params, [ 'reduceOnly', 'stop', 'stopPrice', 'orderType', 'triggerPrice', 'algoPrice', 'priceType', 'bizType' ]);
|
1833
|
+
let response = await this[method] (this.extend (request, query));
|
1834
|
+
//
|
1835
|
+
// Spot
|
1836
|
+
//
|
1837
|
+
// {
|
1838
|
+
// "code": 1000,
|
1839
|
+
// "message": "操作成功",
|
1840
|
+
// "id": "202202224851151555"
|
1841
|
+
// }
|
1842
|
+
//
|
1843
|
+
// Swap
|
1844
|
+
//
|
1845
|
+
// {
|
1846
|
+
// "code": 10000,
|
1847
|
+
// "desc": "操作成功",
|
1848
|
+
// "data": {
|
1849
|
+
// "orderId": "6901786759944937472",
|
1850
|
+
// "orderCode": null
|
1851
|
+
// }
|
1852
|
+
// }
|
1853
|
+
//
|
1854
|
+
// Algo order
|
1855
|
+
//
|
1856
|
+
// {
|
1857
|
+
// "code": 10000,
|
1858
|
+
// "data": "6919884551305242624",
|
1859
|
+
// "desc": "操作成功"
|
1860
|
+
// }
|
1861
|
+
//
|
1862
|
+
if (swap && stop === undefined && stopPrice === undefined) {
|
1863
|
+
response = this.safeValue (response, 'data');
|
1864
|
+
response['timeInForce'] = timeInForce;
|
1865
|
+
response['type'] = request['tradeType'];
|
1866
|
+
response['total_amount'] = amount;
|
1867
|
+
response['price'] = price;
|
1868
|
+
}
|
1869
|
+
return this.parseOrder (response, market);
|
1870
|
+
}
|
1871
|
+
|
1872
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
1873
|
+
if (symbol === undefined) {
|
1874
|
+
throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
|
1875
|
+
}
|
1876
|
+
await this.loadMarkets ();
|
1877
|
+
const market = this.market (symbol);
|
1878
|
+
const swap = market['swap'];
|
1879
|
+
const request = {
|
1880
|
+
// 'currency': this.marketId (symbol), // only applicable to SPOT
|
1881
|
+
// 'id': id.toString (), // only applicable to SPOT
|
1882
|
+
// 'symbol': this.marketId (symbol), // only applicable to SWAP
|
1883
|
+
// 'orderId': id.toString (), // only applicable to SWAP
|
1884
|
+
// 'clientOrderId': params['clientOrderId'], // only applicable to SWAP
|
1885
|
+
};
|
1886
|
+
const marketIdField = swap ? 'symbol' : 'currency';
|
1887
|
+
request[marketIdField] = this.marketId (symbol);
|
1888
|
+
const orderIdField = swap ? 'orderId' : 'id';
|
1889
|
+
request[orderIdField] = id.toString ();
|
1890
|
+
const method = this.getSupportedMapping (market['type'], {
|
1891
|
+
'spot': 'spotV1PrivateGetCancelOrder',
|
1892
|
+
'swap': 'contractV2PrivatePostTradeCancelOrder',
|
1893
|
+
});
|
1894
|
+
const response = await this[method] (this.extend (request, params));
|
1895
|
+
//
|
1896
|
+
// Spot
|
1897
|
+
//
|
1898
|
+
// {
|
1899
|
+
// "code": 1000,
|
1900
|
+
// "message": "Success。"
|
1901
|
+
// }
|
1902
|
+
//
|
1903
|
+
// Swap
|
1904
|
+
//
|
1905
|
+
// {
|
1906
|
+
// "code": 10007,
|
1907
|
+
// "desc": "orderId与clientOrderId选填1个"
|
1908
|
+
// }
|
1909
|
+
//
|
1910
|
+
return this.parseOrder (response, market);
|
1911
|
+
}
|
1912
|
+
|
1913
|
+
async cancelAllOrders (symbol = undefined, params = {}) {
|
1914
|
+
if (symbol === undefined) {
|
1915
|
+
throw new ArgumentsRequired (this.id + ' cancelAllOrders() requires a symbol argument');
|
1916
|
+
}
|
1917
|
+
await this.loadMarkets ();
|
1918
|
+
const market = this.market (symbol);
|
1919
|
+
const stop = this.safeValue (params, 'stop');
|
1920
|
+
if (market['spot']) {
|
1921
|
+
throw new NotSupported (this.id + ' cancelAllOrders() is not supported on ' + market['type'] + ' markets');
|
1922
|
+
}
|
1923
|
+
const request = {
|
1924
|
+
'symbol': market['id'],
|
1925
|
+
// 'ids': [ 6904603200733782016, 6819506476072247297 ], // STOP
|
1926
|
+
// 'side': params['side'], // STOP, for stop orders: 1 Open long (buy), 2 Open short (sell), 3 Close long (sell), 4 Close Short (Buy). One-Way Positions: 5 Buy, 6 Sell, 0 Close Only
|
1927
|
+
};
|
1928
|
+
let method = 'contractV2PrivatePostTradeCancelAllOrders';
|
1929
|
+
if (stop) {
|
1930
|
+
method = 'contractV2PrivatePostTradeCancelAlgos';
|
1931
|
+
}
|
1932
|
+
const query = this.omit (params, 'stop');
|
1933
|
+
return await this[method] (this.extend (request, query));
|
1934
|
+
}
|
1935
|
+
|
1936
|
+
async fetchOrder (id, symbol = undefined, params = {}) {
|
1937
|
+
if (symbol === undefined) {
|
1938
|
+
throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument');
|
1939
|
+
}
|
1940
|
+
await this.loadMarkets ();
|
1941
|
+
const market = this.market (symbol);
|
1942
|
+
const reduceOnly = this.safeValue (params, 'reduceOnly');
|
1943
|
+
const stop = this.safeValue (params, 'stop');
|
1944
|
+
const swap = market['swap'];
|
1945
|
+
const request = {
|
1946
|
+
// 'currency': this.marketId (symbol), // only applicable to SPOT
|
1947
|
+
// 'id': id.toString (), // only applicable to SPOT
|
1948
|
+
// 'orderId': id.toString (), // only applicable to SWAP
|
1949
|
+
// 'clientOrderId': params['clientOrderId'], // only applicable to SWAP
|
1950
|
+
// 'symbol': market['id'], // STOP and SWAP
|
1951
|
+
// 'side': params['side'], // STOP and SWAP, for stop orders: 1 Open long (buy), 2 Open short (sell), 3 Close long (sell), 4 Close Short (Buy). One-Way Positions: 5 Buy, 6 Sell, 0 Close Only
|
1952
|
+
// 'orderType': 1, // STOP, 1: Plan order, 2: SP/SL
|
1953
|
+
// 'bizType': 1, // Plan order, 1: TP, 2: SL
|
1954
|
+
// 'status': 1, // STOP, 1: untriggered, 2: cancelled, 3:triggered, 4:failed, 5:completed
|
1955
|
+
// 'startTime': since, // STOP and SWAP
|
1956
|
+
// 'endTime': params['endTime'], // STOP and SWAP
|
1957
|
+
// 'pageNum': 1, // STOP and SWAP, default 1
|
1958
|
+
// 'pageSize': limit, // STOP, default 10
|
1959
|
+
};
|
1960
|
+
const marketIdField = swap ? 'symbol' : 'currency';
|
1961
|
+
request[marketIdField] = this.marketId (symbol);
|
1962
|
+
const orderIdField = swap ? 'orderId' : 'id';
|
1963
|
+
request[orderIdField] = id.toString ();
|
1964
|
+
let method = this.getSupportedMapping (market['type'], {
|
1965
|
+
'spot': 'spotV1PrivateGetGetOrder',
|
1966
|
+
'swap': 'contractV2PrivateGetTradeGetOrder',
|
1967
|
+
});
|
1968
|
+
if (stop) {
|
1969
|
+
method = 'contractV2PrivateGetTradeGetOrderAlgos';
|
1970
|
+
const orderType = this.safeInteger (params, 'orderType');
|
1971
|
+
if (orderType === undefined) {
|
1972
|
+
throw new ArgumentsRequired (this.id + ' fetchOrder() requires an orderType parameter for stop orders');
|
1973
|
+
}
|
1974
|
+
const side = this.safeInteger (params, 'side');
|
1975
|
+
const bizType = this.safeInteger (params, 'bizType');
|
1976
|
+
if (side === 'sell' && reduceOnly) {
|
1977
|
+
request['side'] = 3; // close long
|
1978
|
+
} else if (side === 'buy' && reduceOnly) {
|
1979
|
+
request['side'] = 4; // close short
|
1980
|
+
} else if (side === 'buy') {
|
1981
|
+
request['side'] = 1; // open long
|
1982
|
+
} else if (side === 'sell') {
|
1983
|
+
request['side'] = 2; // open short
|
1984
|
+
} else if (side === 5) {
|
1985
|
+
request['side'] = 5; // one way position buy
|
1986
|
+
} else if (side === 6) {
|
1987
|
+
request['side'] = 6; // one way position sell
|
1988
|
+
} else if (side === 0) {
|
1989
|
+
request['side'] = 0; // one way position close only
|
1990
|
+
}
|
1991
|
+
if (orderType === 1) {
|
1992
|
+
request['orderType'] = 1;
|
1993
|
+
} else if (orderType === 2 || bizType) {
|
1994
|
+
request['orderType'] = 2;
|
1995
|
+
request['bizType'] = bizType;
|
1996
|
+
}
|
1997
|
+
}
|
1998
|
+
const query = this.omit (params, [ 'reduceOnly', 'stop', 'side', 'orderType', 'bizType' ]);
|
1999
|
+
let response = await this[method] (this.extend (request, query));
|
2000
|
+
//
|
2001
|
+
// Spot
|
2002
|
+
//
|
2003
|
+
// {
|
2004
|
+
// 'total_amount': 0.01,
|
2005
|
+
// 'id': '20180910244276459',
|
2006
|
+
// 'price': 180.0,
|
2007
|
+
// 'trade_date': 1536576744960,
|
2008
|
+
// 'status': 2,
|
2009
|
+
// 'trade_money': '1.96742',
|
2010
|
+
// 'trade_amount': 0.01,
|
2011
|
+
// 'type': 0,
|
2012
|
+
// 'currency': 'eth_usdt'
|
2013
|
+
// }
|
2014
|
+
//
|
2015
|
+
// Swap
|
2016
|
+
//
|
2017
|
+
// {
|
2018
|
+
// "code": 10000,
|
2019
|
+
// "data": {
|
2020
|
+
// "action": 1,
|
2021
|
+
// "amount": "0.002",
|
2022
|
+
// "availableAmount": "0.002",
|
2023
|
+
// "availableValue": "60",
|
2024
|
+
// "avgPrice": "0",
|
2025
|
+
// "canCancel": true,
|
2026
|
+
// "cancelStatus": 20,
|
2027
|
+
// "createTime": "1646185684379",
|
2028
|
+
// "entrustType": 1,
|
2029
|
+
// "id": "6904603200733782016",
|
2030
|
+
// "leverage": 2,
|
2031
|
+
// "margin": "30",
|
2032
|
+
// "marketId": "100",
|
2033
|
+
// "modifyTime": "1646185684416",
|
2034
|
+
// "price": "30000",
|
2035
|
+
// "priority": 0,
|
2036
|
+
// "showStatus": 1,
|
2037
|
+
// "side": 1,
|
2038
|
+
// "sourceType": 4,
|
2039
|
+
// "status": 12,
|
2040
|
+
// "tradeAmount": "0",
|
2041
|
+
// "tradeValue": "0",
|
2042
|
+
// "type": 1,
|
2043
|
+
// "userId": "6896693805014120448",
|
2044
|
+
// "value": "60"
|
2045
|
+
// },
|
2046
|
+
// "desc":"操作成功"
|
2047
|
+
// }
|
2048
|
+
//
|
2049
|
+
// Algo order
|
2050
|
+
//
|
2051
|
+
// {
|
2052
|
+
// "code": 10000,
|
2053
|
+
// "data": {
|
2054
|
+
// "list": [
|
2055
|
+
// {
|
2056
|
+
// "action": 1,
|
2057
|
+
// "algoPrice": "30000",
|
2058
|
+
// "amount": "0.003",
|
2059
|
+
// "bizType": 0,
|
2060
|
+
// "canCancel": true,
|
2061
|
+
// "createTime": "1649913941109",
|
2062
|
+
// "errorCode": 0,
|
2063
|
+
// "id": "6920240642849449984",
|
2064
|
+
// "isLong": false,
|
2065
|
+
// "leverage": 10,
|
2066
|
+
// "marketId": "100",
|
2067
|
+
// "modifyTime": "1649913941109",
|
2068
|
+
// "orderType": 1,
|
2069
|
+
// "priceType": 2,
|
2070
|
+
// "side": 5,
|
2071
|
+
// "sourceType": 4,
|
2072
|
+
// "status": 1,
|
2073
|
+
// "submitPrice": "41270.53",
|
2074
|
+
// "symbol": "BTC_USDT",
|
2075
|
+
// "tradedAmount": "0",
|
2076
|
+
// "triggerCondition": "<=",
|
2077
|
+
// "triggerPrice": "31000",
|
2078
|
+
// "triggerTime": "0",
|
2079
|
+
// "userId": "6896693805014120448"
|
2080
|
+
// },
|
2081
|
+
// ],
|
2082
|
+
// "pageNum": 1,
|
2083
|
+
// "pageSize": 10
|
2084
|
+
// },
|
2085
|
+
// "desc": "操作成功"
|
2086
|
+
// }
|
2087
|
+
//
|
2088
|
+
if (stop) {
|
2089
|
+
const data = this.safeValue (response, 'data', {});
|
2090
|
+
response = this.safeValue (data, 'list', []);
|
2091
|
+
const result = [];
|
2092
|
+
for (let i = 0; i < response.length; i++) {
|
2093
|
+
const entry = response[i];
|
2094
|
+
const algoId = this.safeString (entry, 'id');
|
2095
|
+
if (id === algoId) {
|
2096
|
+
result.push (entry);
|
2097
|
+
}
|
2098
|
+
}
|
2099
|
+
response = result[0];
|
2100
|
+
}
|
2101
|
+
if (swap && !stop) {
|
2102
|
+
response = this.safeValue (response, 'data', {});
|
2103
|
+
}
|
2104
|
+
return this.parseOrder (response, market);
|
2105
|
+
}
|
2106
|
+
|
2107
|
+
async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2108
|
+
if (symbol === undefined) {
|
2109
|
+
throw new ArgumentsRequired (this.id + ' fetchOrders() requires a symbol argument');
|
2110
|
+
}
|
2111
|
+
await this.loadMarkets ();
|
2112
|
+
const market = this.market (symbol);
|
2113
|
+
const reduceOnly = this.safeValue (params, 'reduceOnly');
|
2114
|
+
const stop = this.safeValue (params, 'stop');
|
2115
|
+
const swap = market['swap'];
|
2116
|
+
const request = {
|
2117
|
+
'pageSize': limit, // default pageSize is 50 for spot, 30 for swap
|
2118
|
+
// 'currency': market['id'], // only applicable to SPOT
|
2119
|
+
// 'pageIndex': 1, // only applicable to SPOT
|
2120
|
+
// 'type': params['type'], // only applicable to SWAP
|
2121
|
+
// 'dateRange': params['dateRange'], // only applicable to SWAP
|
2122
|
+
// 'action': params['action'], // only applicable to SWAP
|
2123
|
+
// 'symbol': market['id'], // STOP and SWAP
|
2124
|
+
// 'side': params['side'], // STOP and SWAP, for stop orders: 1 Open long (buy), 2 Open short (sell), 3 Close long (sell), 4 Close Short (Buy). One-Way Positions: 5 Buy, 6 Sell, 0 Close Only
|
2125
|
+
// 'orderType': 1, // STOP, 1: Plan order, 2: SP/SL
|
2126
|
+
// 'bizType': 1, // Plan order, 1: TP, 2: SL
|
2127
|
+
// 'status': 1, // STOP, 1: untriggered, 2: cancelled, 3:triggered, 4:failed, 5:completed
|
2128
|
+
// 'startTime': since, // STOP and SWAP
|
2129
|
+
// 'endTime': params['endTime'], // STOP and SWAP
|
2130
|
+
// 'pageNum': 1, // STOP and SWAP, default 1
|
2131
|
+
// 'pageSize': limit, // STOP, default 10
|
2132
|
+
};
|
2133
|
+
const marketIdField = market['swap'] ? 'symbol' : 'currency';
|
2134
|
+
request[marketIdField] = market['id'];
|
2135
|
+
const pageNumField = market['swap'] ? 'pageNum' : 'pageIndex';
|
2136
|
+
request[pageNumField] = 1;
|
2137
|
+
if (swap) {
|
2138
|
+
request['startTime'] = since;
|
2139
|
+
}
|
2140
|
+
let method = this.getSupportedMapping (market['type'], {
|
2141
|
+
'spot': 'spotV1PrivateGetGetOrdersIgnoreTradeType',
|
2142
|
+
'swap': 'contractV2PrivateGetTradeGetAllOrders',
|
2143
|
+
});
|
2144
|
+
// tradeType 交易类型1/0[buy/sell]
|
2145
|
+
if ('tradeType' in params) {
|
2146
|
+
method = 'spotV1PrivateGetGetOrdersNew';
|
2147
|
+
}
|
2148
|
+
if (stop) {
|
2149
|
+
method = 'contractV2PrivateGetTradeGetOrderAlgos';
|
2150
|
+
const orderType = this.safeInteger (params, 'orderType');
|
2151
|
+
if (orderType === undefined) {
|
2152
|
+
throw new ArgumentsRequired (this.id + ' fetchOrders() requires an orderType parameter for stop orders');
|
2153
|
+
}
|
2154
|
+
const side = this.safeInteger (params, 'side');
|
2155
|
+
const bizType = this.safeInteger (params, 'bizType');
|
2156
|
+
if (side === 'sell' && reduceOnly) {
|
2157
|
+
request['side'] = 3; // close long
|
2158
|
+
} else if (side === 'buy' && reduceOnly) {
|
2159
|
+
request['side'] = 4; // close short
|
2160
|
+
} else if (side === 'buy') {
|
2161
|
+
request['side'] = 1; // open long
|
2162
|
+
} else if (side === 'sell') {
|
2163
|
+
request['side'] = 2; // open short
|
2164
|
+
} else if (side === 5) {
|
2165
|
+
request['side'] = 5; // one way position buy
|
2166
|
+
} else if (side === 6) {
|
2167
|
+
request['side'] = 6; // one way position sell
|
2168
|
+
} else if (side === 0) {
|
2169
|
+
request['side'] = 0; // one way position close only
|
2170
|
+
}
|
2171
|
+
if (orderType === 1) {
|
2172
|
+
request['orderType'] = 1;
|
2173
|
+
} else if (orderType === 2 || bizType) {
|
2174
|
+
request['orderType'] = 2;
|
2175
|
+
request['bizType'] = bizType;
|
2176
|
+
}
|
2177
|
+
}
|
2178
|
+
const query = this.omit (params, [ 'reduceOnly', 'stop', 'side', 'orderType', 'bizType' ]);
|
2179
|
+
let response = undefined;
|
2180
|
+
try {
|
2181
|
+
response = await this[method] (this.extend (request, query));
|
2182
|
+
} catch (e) {
|
2183
|
+
if (e instanceof OrderNotFound) {
|
2184
|
+
return [];
|
2185
|
+
}
|
2186
|
+
throw e;
|
2187
|
+
}
|
2188
|
+
// Spot
|
2189
|
+
//
|
2190
|
+
// [
|
2191
|
+
// {
|
2192
|
+
// "acctType": 0,
|
2193
|
+
// "currency": "btc_usdt",
|
2194
|
+
// "fees": 0,
|
2195
|
+
// "id": "202202234857482656",
|
2196
|
+
// "price": 30000.0,
|
2197
|
+
// "status": 3,
|
2198
|
+
// "total_amount": 0.0006,
|
2199
|
+
// "trade_amount": 0.0000,
|
2200
|
+
// "trade_date": 1645610254524,
|
2201
|
+
// "trade_money": 0.000000,
|
2202
|
+
// "type": 1,
|
2203
|
+
// "useZbFee": false,
|
2204
|
+
// "webId": 0
|
2205
|
+
// }
|
2206
|
+
// ]
|
2207
|
+
//
|
2208
|
+
// Swap
|
2209
|
+
//
|
2210
|
+
// {
|
2211
|
+
// "code": 10000,
|
2212
|
+
// "data": {
|
2213
|
+
// "list": [
|
2214
|
+
// {
|
2215
|
+
// "action": 1,
|
2216
|
+
// "amount": "0.004",
|
2217
|
+
// "availableAmount": "0.004",
|
2218
|
+
// "availableValue": "120",
|
2219
|
+
// "avgPrice": "0",
|
2220
|
+
// "canCancel": true,
|
2221
|
+
// "cancelStatus": 20,
|
2222
|
+
// "createTime": "1645609643885",
|
2223
|
+
// "entrustType": 1,
|
2224
|
+
// "id": "6902187111785635850",
|
2225
|
+
// "leverage": 5,
|
2226
|
+
// "margin": "24",
|
2227
|
+
// "marketId": "100",
|
2228
|
+
// "marketName": "BTC_USDT",
|
2229
|
+
// "modifyTime": "1645609643889",
|
2230
|
+
// "price": "30000",
|
2231
|
+
// "showStatus": 1,
|
2232
|
+
// "side": 1,
|
2233
|
+
// "sourceType": 1,
|
2234
|
+
// "status": 12,
|
2235
|
+
// "tradeAmount": "0",
|
2236
|
+
// "tradeValue": "0",
|
2237
|
+
// "type": 1,
|
2238
|
+
// "userId": "6896693805014120448",
|
2239
|
+
// "value": "120"
|
2240
|
+
// },
|
2241
|
+
// ],
|
2242
|
+
// "pageNum": 1,
|
2243
|
+
// "pageSize": 10
|
2244
|
+
// },
|
2245
|
+
// "desc": "操作成功"
|
2246
|
+
// }
|
2247
|
+
//
|
2248
|
+
// Algo order
|
2249
|
+
//
|
2250
|
+
// {
|
2251
|
+
// "code": 10000,
|
2252
|
+
// "data": {
|
2253
|
+
// "list": [
|
2254
|
+
// {
|
2255
|
+
// "action": 1,
|
2256
|
+
// "algoPrice": "30000",
|
2257
|
+
// "amount": "0.003",
|
2258
|
+
// "bizType": 0,
|
2259
|
+
// "canCancel": true,
|
2260
|
+
// "createTime": "1649913941109",
|
2261
|
+
// "errorCode": 0,
|
2262
|
+
// "id": "6920240642849449984",
|
2263
|
+
// "isLong": false,
|
2264
|
+
// "leverage": 10,
|
2265
|
+
// "marketId": "100",
|
2266
|
+
// "modifyTime": "1649913941109",
|
2267
|
+
// "orderType": 1,
|
2268
|
+
// "priceType": 2,
|
2269
|
+
// "side": 5,
|
2270
|
+
// "sourceType": 4,
|
2271
|
+
// "status": 1,
|
2272
|
+
// "submitPrice": "41270.53",
|
2273
|
+
// "symbol": "BTC_USDT",
|
2274
|
+
// "tradedAmount": "0",
|
2275
|
+
// "triggerCondition": "<=",
|
2276
|
+
// "triggerPrice": "31000",
|
2277
|
+
// "triggerTime": "0",
|
2278
|
+
// "userId": "6896693805014120448"
|
2279
|
+
// },
|
2280
|
+
// ],
|
2281
|
+
// "pageNum": 1,
|
2282
|
+
// "pageSize": 10
|
2283
|
+
// },
|
2284
|
+
// "desc": "操作成功"
|
2285
|
+
// }
|
2286
|
+
//
|
2287
|
+
if (swap) {
|
2288
|
+
const data = this.safeValue (response, 'data', {});
|
2289
|
+
response = this.safeValue (data, 'list', []);
|
2290
|
+
}
|
2291
|
+
return this.parseOrders (response, market, since, limit);
|
2292
|
+
}
|
2293
|
+
|
2294
|
+
async fetchCanceledOrders (symbol = undefined, since = undefined, limit = 10, params = {}) {
|
2295
|
+
if (symbol === undefined) {
|
2296
|
+
throw new ArgumentsRequired (this.id + ' fetchCanceledOrders() requires a symbol argument');
|
2297
|
+
}
|
2298
|
+
await this.loadMarkets ();
|
2299
|
+
const market = this.market (symbol);
|
2300
|
+
const reduceOnly = this.safeValue (params, 'reduceOnly');
|
2301
|
+
const stop = this.safeValue (params, 'stop');
|
2302
|
+
const request = {
|
2303
|
+
'pageSize': limit, // SPOT and STOP, default pageSize is 10, doesn't work with other values now
|
2304
|
+
// 'currency': market['id'], // SPOT
|
2305
|
+
// 'pageIndex': 1, // SPOT, default pageIndex is 1
|
2306
|
+
// 'symbol': market['id'], // STOP
|
2307
|
+
// 'side': params['side'], // STOP, for stop orders: 1 Open long (buy), 2 Open short (sell), 3 Close long (sell), 4 Close Short (Buy). One-Way Positions: 5 Buy, 6 Sell, 0 Close Only
|
2308
|
+
// 'orderType': 1, // STOP, 1: Plan order, 2: SP/SL
|
2309
|
+
// 'bizType': 1, // Plan order, 1: TP, 2: SL
|
2310
|
+
// 'status': 1, // STOP, 1: untriggered, 2: cancelled, 3:triggered, 4:failed, 5:completed
|
2311
|
+
// 'startTime': since, // STOP
|
2312
|
+
// 'endTime': params['endTime'], // STOP
|
2313
|
+
// 'pageNum': 1, // STOP, default 1
|
2314
|
+
};
|
2315
|
+
const marketIdField = market['spot'] ? 'currency' : 'symbol';
|
2316
|
+
request[marketIdField] = market['id'];
|
2317
|
+
const pageNumField = market['spot'] ? 'pageIndex' : 'pageNum';
|
2318
|
+
request[pageNumField] = 1;
|
2319
|
+
let method = 'spotV1PrivateGetGetOrdersIgnoreTradeType';
|
2320
|
+
if (stop) {
|
2321
|
+
method = 'contractV2PrivateGetTradeGetOrderAlgos';
|
2322
|
+
const orderType = this.safeInteger (params, 'orderType');
|
2323
|
+
if (orderType === undefined) {
|
2324
|
+
throw new ArgumentsRequired (this.id + ' fetchCanceledOrders() requires an orderType parameter for stop orders');
|
2325
|
+
}
|
2326
|
+
const side = this.safeInteger (params, 'side');
|
2327
|
+
const bizType = this.safeInteger (params, 'bizType');
|
2328
|
+
if (side === 'sell' && reduceOnly) {
|
2329
|
+
request['side'] = 3; // close long
|
2330
|
+
} else if (side === 'buy' && reduceOnly) {
|
2331
|
+
request['side'] = 4; // close short
|
2332
|
+
} else if (side === 'buy') {
|
2333
|
+
request['side'] = 1; // open long
|
2334
|
+
} else if (side === 'sell') {
|
2335
|
+
request['side'] = 2; // open short
|
2336
|
+
} else if (side === 5) {
|
2337
|
+
request['side'] = 5; // one way position buy
|
2338
|
+
} else if (side === 6) {
|
2339
|
+
request['side'] = 6; // one way position sell
|
2340
|
+
} else if (side === 0) {
|
2341
|
+
request['side'] = 0; // one way position close only
|
2342
|
+
}
|
2343
|
+
if (orderType === 1) {
|
2344
|
+
request['orderType'] = 1;
|
2345
|
+
} else if (orderType === 2 || bizType) {
|
2346
|
+
request['orderType'] = 2;
|
2347
|
+
request['bizType'] = bizType;
|
2348
|
+
}
|
2349
|
+
request['status'] = 2;
|
2350
|
+
}
|
2351
|
+
// tradeType 交易类型1/0[buy/sell]
|
2352
|
+
if ('tradeType' in params) {
|
2353
|
+
method = 'spotV1PrivateGetGetOrdersNew';
|
2354
|
+
}
|
2355
|
+
let response = undefined;
|
2356
|
+
try {
|
2357
|
+
response = await this[method] (this.extend (request, params));
|
2358
|
+
} catch (e) {
|
2359
|
+
if (e instanceof OrderNotFound) {
|
2360
|
+
return [];
|
2361
|
+
}
|
2362
|
+
throw e;
|
2363
|
+
}
|
2364
|
+
const query = this.omit (params, [ 'reduceOnly', 'stop', 'side', 'orderType', 'bizType' ]);
|
2365
|
+
response = await this[method] (this.extend (request, query));
|
2366
|
+
//
|
2367
|
+
// Spot
|
2368
|
+
//
|
2369
|
+
// [
|
2370
|
+
// {
|
2371
|
+
// "acctType": 0,
|
2372
|
+
// "currency": "btc_usdt",
|
2373
|
+
// "fees": 0,
|
2374
|
+
// "id": "202202234857482656",
|
2375
|
+
// "price": 30000.0,
|
2376
|
+
// "status": 1,
|
2377
|
+
// "total_amount": 0.0006,
|
2378
|
+
// "trade_amount": 0.0000,
|
2379
|
+
// "trade_date": 1645610254524,
|
2380
|
+
// "trade_money": 0.000000,
|
2381
|
+
// "type": 1,
|
2382
|
+
// "useZbFee": false,
|
2383
|
+
// "webId": 0
|
2384
|
+
// }
|
2385
|
+
// ]
|
2386
|
+
//
|
2387
|
+
// Algo order
|
2388
|
+
//
|
2389
|
+
// {
|
2390
|
+
// "code": 10000,
|
2391
|
+
// "data": {
|
2392
|
+
// "list": [
|
2393
|
+
// {
|
2394
|
+
// "action": 1,
|
2395
|
+
// "algoPrice": "30000",
|
2396
|
+
// "amount": "0.003",
|
2397
|
+
// "bizType": 0,
|
2398
|
+
// "canCancel": true,
|
2399
|
+
// "createTime": "1649913941109",
|
2400
|
+
// "errorCode": 0,
|
2401
|
+
// "id": "6920240642849449984",
|
2402
|
+
// "isLong": false,
|
2403
|
+
// "leverage": 10,
|
2404
|
+
// "marketId": "100",
|
2405
|
+
// "modifyTime": "1649913941109",
|
2406
|
+
// "orderType": 1,
|
2407
|
+
// "priceType": 2,
|
2408
|
+
// "side": 5,
|
2409
|
+
// "sourceType": 4,
|
2410
|
+
// "status": 2,
|
2411
|
+
// "submitPrice": "41270.53",
|
2412
|
+
// "symbol": "BTC_USDT",
|
2413
|
+
// "tradedAmount": "0",
|
2414
|
+
// "triggerCondition": "<=",
|
2415
|
+
// "triggerPrice": "31000",
|
2416
|
+
// "triggerTime": "0",
|
2417
|
+
// "userId": "6896693805014120448"
|
2418
|
+
// },
|
2419
|
+
// ],
|
2420
|
+
// "pageNum": 1,
|
2421
|
+
// "pageSize": 10
|
2422
|
+
// },
|
2423
|
+
// "desc": "操作成功"
|
2424
|
+
// }
|
2425
|
+
//
|
2426
|
+
if (stop) {
|
2427
|
+
const data = this.safeValue (response, 'data', {});
|
2428
|
+
response = this.safeValue (data, 'list', []);
|
2429
|
+
}
|
2430
|
+
const result = [];
|
2431
|
+
if (market['type'] === 'spot') {
|
2432
|
+
for (let i = 0; i < response.length; i++) {
|
2433
|
+
const entry = response[i];
|
2434
|
+
const status = this.safeString (entry, 'status');
|
2435
|
+
if (status === '1') {
|
2436
|
+
result.push (entry);
|
2437
|
+
}
|
2438
|
+
}
|
2439
|
+
response = result;
|
2440
|
+
}
|
2441
|
+
return this.parseOrders (response, market, since, limit);
|
2442
|
+
}
|
2443
|
+
|
2444
|
+
async fetchClosedOrders (symbol = undefined, since = undefined, limit = 10, params = {}) {
|
2445
|
+
if (symbol === undefined) {
|
2446
|
+
throw new ArgumentsRequired (this.id + ' fetchClosedOrders() requires a symbol argument');
|
2447
|
+
}
|
2448
|
+
await this.loadMarkets ();
|
2449
|
+
const market = this.market (symbol);
|
2450
|
+
const reduceOnly = this.safeValue (params, 'reduceOnly');
|
2451
|
+
const stop = this.safeValue (params, 'stop');
|
2452
|
+
const request = {
|
2453
|
+
'pageSize': limit, // SPOT and STOP, default pageSize is 10, doesn't work with other values now
|
2454
|
+
// 'currency': market['id'], // SPOT
|
2455
|
+
// 'pageIndex': 1, // SPOT, default pageIndex is 1
|
2456
|
+
// 'symbol': market['id'], // STOP
|
2457
|
+
// 'side': params['side'], // STOP, for stop orders: 1 Open long (buy), 2 Open short (sell), 3 Close long (sell), 4 Close Short (Buy). One-Way Positions: 5 Buy, 6 Sell, 0 Close Only
|
2458
|
+
// 'orderType': 1, // STOP, 1: Plan order, 2: SP/SL
|
2459
|
+
// 'bizType': 1, // Plan order, 1: TP, 2: SL
|
2460
|
+
// 'status': 1, // STOP, 1: untriggered, 2: cancelled, 3:triggered, 4:failed, 5:completed
|
2461
|
+
// 'startTime': since, // STOP
|
2462
|
+
// 'endTime': params['endTime'], // STOP
|
2463
|
+
// 'pageNum': 1, // STOP, default 1
|
2464
|
+
};
|
2465
|
+
const marketIdField = market['spot'] ? 'currency' : 'symbol';
|
2466
|
+
request[marketIdField] = market['id'];
|
2467
|
+
const pageNumField = market['spot'] ? 'pageIndex' : 'pageNum';
|
2468
|
+
request[pageNumField] = 1;
|
2469
|
+
let method = 'spotV1PrivateGetGetFinishedAndPartialOrders';
|
2470
|
+
if (stop) {
|
2471
|
+
method = 'contractV2PrivateGetTradeGetOrderAlgos';
|
2472
|
+
const orderType = this.safeInteger (params, 'orderType');
|
2473
|
+
if (orderType === undefined) {
|
2474
|
+
throw new ArgumentsRequired (this.id + ' fetchClosedOrders() requires an orderType parameter for stop orders');
|
2475
|
+
}
|
2476
|
+
const side = this.safeInteger (params, 'side');
|
2477
|
+
const bizType = this.safeInteger (params, 'bizType');
|
2478
|
+
if (side === 'sell' && reduceOnly) {
|
2479
|
+
request['side'] = 3; // close long
|
2480
|
+
} else if (side === 'buy' && reduceOnly) {
|
2481
|
+
request['side'] = 4; // close short
|
2482
|
+
} else if (side === 'buy') {
|
2483
|
+
request['side'] = 1; // open long
|
2484
|
+
} else if (side === 'sell') {
|
2485
|
+
request['side'] = 2; // open short
|
2486
|
+
} else if (side === 5) {
|
2487
|
+
request['side'] = 5; // one way position buy
|
2488
|
+
} else if (side === 6) {
|
2489
|
+
request['side'] = 6; // one way position sell
|
2490
|
+
} else if (side === 0) {
|
2491
|
+
request['side'] = 0; // one way position close only
|
2492
|
+
}
|
2493
|
+
if (orderType === 1) {
|
2494
|
+
request['orderType'] = 1;
|
2495
|
+
} else if (orderType === 2 || bizType) {
|
2496
|
+
request['orderType'] = 2;
|
2497
|
+
request['bizType'] = bizType;
|
2498
|
+
}
|
2499
|
+
request['status'] = 5;
|
2500
|
+
}
|
2501
|
+
const query = this.omit (params, [ 'reduceOnly', 'stop', 'side', 'orderType', 'bizType' ]);
|
2502
|
+
let response = await this[method] (this.extend (request, query));
|
2503
|
+
//
|
2504
|
+
// Spot
|
2505
|
+
//
|
2506
|
+
// [
|
2507
|
+
// {
|
2508
|
+
// "acctType": 0,
|
2509
|
+
// "currency": "btc_usdt",
|
2510
|
+
// "fees": 0.00823354,
|
2511
|
+
// "id": "202204145086706337",
|
2512
|
+
// "price": 41167.7,
|
2513
|
+
// "status": 2,
|
2514
|
+
// "total_amount": 0.0001,
|
2515
|
+
// "trade_amount": 0.0001,
|
2516
|
+
// "trade_date": 1649917867370,
|
2517
|
+
// "trade_money": 4.116770,
|
2518
|
+
// "type": 0,
|
2519
|
+
// "useZbFee": false,
|
2520
|
+
// "webId": 0
|
2521
|
+
// },
|
2522
|
+
// ]
|
2523
|
+
//
|
2524
|
+
// Algo order
|
2525
|
+
//
|
2526
|
+
// {
|
2527
|
+
// "code": 10000,
|
2528
|
+
// "data": {
|
2529
|
+
// "list": [
|
2530
|
+
// {
|
2531
|
+
// "action": 1,
|
2532
|
+
// "algoPrice": "30000",
|
2533
|
+
// "amount": "0.003",
|
2534
|
+
// "bizType": 0,
|
2535
|
+
// "canCancel": true,
|
2536
|
+
// "createTime": "1649913941109",
|
2537
|
+
// "errorCode": 0,
|
2538
|
+
// "id": "6920240642849449984",
|
2539
|
+
// "isLong": false,
|
2540
|
+
// "leverage": 10,
|
2541
|
+
// "marketId": "100",
|
2542
|
+
// "modifyTime": "1649913941109",
|
2543
|
+
// "orderType": 1,
|
2544
|
+
// "priceType": 2,
|
2545
|
+
// "side": 5,
|
2546
|
+
// "sourceType": 4,
|
2547
|
+
// "status": 1,
|
2548
|
+
// "submitPrice": "41270.53",
|
2549
|
+
// "symbol": "BTC_USDT",
|
2550
|
+
// "tradedAmount": "0",
|
2551
|
+
// "triggerCondition": "<=",
|
2552
|
+
// "triggerPrice": "31000",
|
2553
|
+
// "triggerTime": "0",
|
2554
|
+
// "userId": "6896693805014120448"
|
2555
|
+
// },
|
2556
|
+
// ],
|
2557
|
+
// "pageNum": 1,
|
2558
|
+
// "pageSize": 10
|
2559
|
+
// },
|
2560
|
+
// "desc": "操作成功"
|
2561
|
+
// }
|
2562
|
+
//
|
2563
|
+
if (stop) {
|
2564
|
+
const data = this.safeValue (response, 'data', {});
|
2565
|
+
response = this.safeValue (data, 'list', []);
|
2566
|
+
}
|
2567
|
+
return this.parseOrders (response, market, since, limit);
|
2568
|
+
}
|
2569
|
+
|
2570
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
2571
|
+
if (symbol === undefined) {
|
2572
|
+
throw new ArgumentsRequired (this.id + ' fetchOpenOrders() requires a symbol argument');
|
2573
|
+
}
|
2574
|
+
await this.loadMarkets ();
|
2575
|
+
const market = this.market (symbol);
|
2576
|
+
const reduceOnly = this.safeValue (params, 'reduceOnly');
|
2577
|
+
const stop = this.safeValue (params, 'stop');
|
2578
|
+
const swap = market['swap'];
|
2579
|
+
const request = {
|
2580
|
+
// 'pageSize': limit, // default pageSize is 10 for spot, 30 for swap
|
2581
|
+
// 'currency': market['id'], // SPOT
|
2582
|
+
// 'pageIndex': 1, // SPOT
|
2583
|
+
// 'symbol': market['id'], // SWAP and STOP
|
2584
|
+
// 'pageNum': 1, // SWAP and STOP, default 1
|
2585
|
+
// 'type': params['type'], // swap only
|
2586
|
+
// 'side': params['side'], // SWAP and STOP, for stop orders: 1 Open long (buy), 2 Open short (sell), 3 Close long (sell), 4 Close Short (Buy). One-Way Positions: 5 Buy, 6 Sell, 0 Close Only
|
2587
|
+
// 'action': params['action'], // SWAP
|
2588
|
+
// 'orderType': 1, // STOP, 1: Plan order, 2: SP/SL
|
2589
|
+
// 'bizType': 1, // Plan order, 1: TP, 2: SL
|
2590
|
+
// 'status': 1, // STOP, 1: untriggered, 2: cancelled, 3:triggered, 4:failed, 5:completed
|
2591
|
+
// 'startTime': since, // SWAP and STOP
|
2592
|
+
// 'endTime': params['endTime'], // STOP
|
2593
|
+
};
|
2594
|
+
if (limit !== undefined) {
|
2595
|
+
request['pageSize'] = limit; // default pageSize is 10 for spot, 30 for swap
|
2596
|
+
}
|
2597
|
+
const marketIdField = market['swap'] ? 'symbol' : 'currency';
|
2598
|
+
request[marketIdField] = market['id'];
|
2599
|
+
const pageNumField = market['swap'] ? 'pageNum' : 'pageIndex';
|
2600
|
+
request[pageNumField] = 1;
|
2601
|
+
if (swap && (since !== undefined)) {
|
2602
|
+
request['startTime'] = since;
|
2603
|
+
}
|
2604
|
+
let method = this.getSupportedMapping (market['type'], {
|
2605
|
+
'spot': 'spotV1PrivateGetGetUnfinishedOrdersIgnoreTradeType',
|
2606
|
+
'swap': 'contractV2PrivateGetTradeGetUndoneOrders',
|
2607
|
+
});
|
2608
|
+
if (stop) {
|
2609
|
+
method = 'contractV2PrivateGetTradeGetOrderAlgos';
|
2610
|
+
const orderType = this.safeInteger (params, 'orderType');
|
2611
|
+
if (orderType === undefined) {
|
2612
|
+
throw new ArgumentsRequired (this.id + ' fetchOpenOrders() requires an orderType parameter for stop orders');
|
2613
|
+
}
|
2614
|
+
const side = this.safeInteger (params, 'side');
|
2615
|
+
const bizType = this.safeInteger (params, 'bizType');
|
2616
|
+
if (side === 'sell' && reduceOnly) {
|
2617
|
+
request['side'] = 3; // close long
|
2618
|
+
} else if (side === 'buy' && reduceOnly) {
|
2619
|
+
request['side'] = 4; // close short
|
2620
|
+
} else if (side === 'buy') {
|
2621
|
+
request['side'] = 1; // open long
|
2622
|
+
} else if (side === 'sell') {
|
2623
|
+
request['side'] = 2; // open short
|
2624
|
+
} else if (side === 5) {
|
2625
|
+
request['side'] = 5; // one way position buy
|
2626
|
+
} else if (side === 6) {
|
2627
|
+
request['side'] = 6; // one way position sell
|
2628
|
+
} else if (side === 0) {
|
2629
|
+
request['side'] = 0; // one way position close only
|
2630
|
+
}
|
2631
|
+
if (orderType === 1) {
|
2632
|
+
request['orderType'] = 1;
|
2633
|
+
} else if (orderType === 2 || bizType) {
|
2634
|
+
request['orderType'] = 2;
|
2635
|
+
request['bizType'] = bizType;
|
2636
|
+
}
|
2637
|
+
request['status'] = 1;
|
2638
|
+
}
|
2639
|
+
const query = this.omit (params, [ 'reduceOnly', 'stop', 'side', 'orderType', 'bizType' ]);
|
2640
|
+
// tradeType 交易类型1/0[buy/sell]
|
2641
|
+
if ('tradeType' in params) {
|
2642
|
+
method = 'spotV1PrivateGetGetOrdersNew';
|
2643
|
+
}
|
2644
|
+
let response = undefined;
|
2645
|
+
try {
|
2646
|
+
response = await this[method] (this.extend (request, query));
|
2647
|
+
} catch (e) {
|
2648
|
+
if (e instanceof OrderNotFound) {
|
2649
|
+
return [];
|
2650
|
+
}
|
2651
|
+
throw e;
|
2652
|
+
}
|
2653
|
+
//
|
2654
|
+
// Spot
|
2655
|
+
//
|
2656
|
+
// [
|
2657
|
+
// {
|
2658
|
+
// "currency": "btc_usdt",
|
2659
|
+
// "id": "20150928158614292",
|
2660
|
+
// "price": 1560,
|
2661
|
+
// "status": 3,
|
2662
|
+
// "total_amount": 0.1,
|
2663
|
+
// "trade_amount": 0,
|
2664
|
+
// "trade_date": 1443410396717,
|
2665
|
+
// "trade_money": 0,
|
2666
|
+
// "type": 0,
|
2667
|
+
// "fees": "0.03",
|
2668
|
+
// "useZbFee": true
|
2669
|
+
// },
|
2670
|
+
// ]
|
2671
|
+
//
|
2672
|
+
// Swap
|
2673
|
+
//
|
2674
|
+
// {
|
2675
|
+
// "code": 10000,
|
2676
|
+
// "data": {
|
2677
|
+
// "list": [
|
2678
|
+
// {
|
2679
|
+
// "action": 1,
|
2680
|
+
// "amount": "0.003",
|
2681
|
+
// "availableAmount": "0.003",
|
2682
|
+
// "availableValue": "90",
|
2683
|
+
// "avgPrice": "0",
|
2684
|
+
// "canCancel": true,
|
2685
|
+
// "cancelStatus": 20,
|
2686
|
+
// "createTime": "1645694610880",
|
2687
|
+
// "entrustType": 1,
|
2688
|
+
// "id": "6902543489192632320",
|
2689
|
+
// "leverage": 5,
|
2690
|
+
// "margin": "18",
|
2691
|
+
// "marketId": "100",
|
2692
|
+
// "modifyTime": "1645694610883",
|
2693
|
+
// "price": "30000",
|
2694
|
+
// "priority": 0,
|
2695
|
+
// "showStatus": 1,
|
2696
|
+
// "side": 1,
|
2697
|
+
// "sourceType": 1,
|
2698
|
+
// "status": 12,
|
2699
|
+
// "tradeAmount": "0",
|
2700
|
+
// "tradeValue": "0",
|
2701
|
+
// "type": 1,
|
2702
|
+
// "userId": "6896693805014120448",
|
2703
|
+
// "value": "90"
|
2704
|
+
// }
|
2705
|
+
// ],
|
2706
|
+
// "pageNum": 1,
|
2707
|
+
// "pageSize": 30
|
2708
|
+
// },
|
2709
|
+
// "desc": "操作成功"
|
2710
|
+
// }
|
2711
|
+
//
|
2712
|
+
// Algo order
|
2713
|
+
//
|
2714
|
+
// {
|
2715
|
+
// "code": 10000,
|
2716
|
+
// "data": {
|
2717
|
+
// "list": [
|
2718
|
+
// {
|
2719
|
+
// "action": 1,
|
2720
|
+
// "algoPrice": "30000",
|
2721
|
+
// "amount": "0.003",
|
2722
|
+
// "bizType": 0,
|
2723
|
+
// "canCancel": true,
|
2724
|
+
// "createTime": "1649913941109",
|
2725
|
+
// "errorCode": 0,
|
2726
|
+
// "id": "6920240642849449984",
|
2727
|
+
// "isLong": false,
|
2728
|
+
// "leverage": 10,
|
2729
|
+
// "marketId": "100",
|
2730
|
+
// "modifyTime": "1649913941109",
|
2731
|
+
// "orderType": 1,
|
2732
|
+
// "priceType": 2,
|
2733
|
+
// "side": 5,
|
2734
|
+
// "sourceType": 4,
|
2735
|
+
// "status": 1,
|
2736
|
+
// "submitPrice": "41270.53",
|
2737
|
+
// "symbol": "BTC_USDT",
|
2738
|
+
// "tradedAmount": "0",
|
2739
|
+
// "triggerCondition": "<=",
|
2740
|
+
// "triggerPrice": "31000",
|
2741
|
+
// "triggerTime": "0",
|
2742
|
+
// "userId": "6896693805014120448"
|
2743
|
+
// },
|
2744
|
+
// ],
|
2745
|
+
// "pageNum": 1,
|
2746
|
+
// "pageSize": 10
|
2747
|
+
// },
|
2748
|
+
// "desc": "操作成功"
|
2749
|
+
// }
|
2750
|
+
//
|
2751
|
+
if (swap) {
|
2752
|
+
const data = this.safeValue (response, 'data', {});
|
2753
|
+
response = this.safeValue (data, 'list', []);
|
2754
|
+
}
|
2755
|
+
return this.parseOrders (response, market, since, limit);
|
2756
|
+
}
|
2757
|
+
|
2758
|
+
parseOrder (order, market = undefined) {
|
2759
|
+
//
|
2760
|
+
// Spot fetchOrder, fetchClosedOrders
|
2761
|
+
//
|
2762
|
+
// {
|
2763
|
+
// acctType: 0,
|
2764
|
+
// currency: 'btc_usdt',
|
2765
|
+
// fees: 3.6e-7,
|
2766
|
+
// id: '202102282829772463',
|
2767
|
+
// price: 45177.5,
|
2768
|
+
// status: 2,
|
2769
|
+
// total_amount: 0.0002,
|
2770
|
+
// trade_amount: 0.0002,
|
2771
|
+
// trade_date: 1614515104998,
|
2772
|
+
// trade_money: 8.983712,
|
2773
|
+
// type: 1,
|
2774
|
+
// useZbFee: false
|
2775
|
+
// },
|
2776
|
+
//
|
2777
|
+
// Swap fetchOrder
|
2778
|
+
//
|
2779
|
+
// {
|
2780
|
+
// "action": 1,
|
2781
|
+
// "amount": "0.002",
|
2782
|
+
// "availableAmount": "0.002",
|
2783
|
+
// "availableValue": "60",
|
2784
|
+
// "avgPrice": "0",
|
2785
|
+
// "canCancel": true,
|
2786
|
+
// "cancelStatus": 20,
|
2787
|
+
// "createTime": "1646185684379",
|
2788
|
+
// "entrustType": 1,
|
2789
|
+
// "id": "6904603200733782016",
|
2790
|
+
// "leverage": 2,
|
2791
|
+
// "margin": "30",
|
2792
|
+
// "marketId": "100",
|
2793
|
+
// "modifyTime": "1646185684416",
|
2794
|
+
// "price": "30000",
|
2795
|
+
// "priority": 0,
|
2796
|
+
// "showStatus": 1,
|
2797
|
+
// "side": 1,
|
2798
|
+
// "sourceType": 4,
|
2799
|
+
// "status": 12,
|
2800
|
+
// "tradeAmount": "0",
|
2801
|
+
// "tradeValue": "0",
|
2802
|
+
// "type": 1,
|
2803
|
+
// "userId": "6896693805014120448",
|
2804
|
+
// "value": "60"
|
2805
|
+
// },
|
2806
|
+
//
|
2807
|
+
// Algo fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders
|
2808
|
+
//
|
2809
|
+
// {
|
2810
|
+
// "action": 1,
|
2811
|
+
// "algoPrice": "30000",
|
2812
|
+
// "amount": "0.003",
|
2813
|
+
// "bizType": 0,
|
2814
|
+
// "canCancel": true,
|
2815
|
+
// "createTime": "1649913941109",
|
2816
|
+
// "errorCode": 0,
|
2817
|
+
// "id": "6920240642849449984",
|
2818
|
+
// "isLong": false,
|
2819
|
+
// "leverage": 10,
|
2820
|
+
// "marketId": "100",
|
2821
|
+
// "modifyTime": "1649913941109",
|
2822
|
+
// "orderType": 1,
|
2823
|
+
// "priceType": 2,
|
2824
|
+
// "side": 5,
|
2825
|
+
// "sourceType": 4,
|
2826
|
+
// "status": 1,
|
2827
|
+
// "submitPrice": "41270.53",
|
2828
|
+
// "symbol": "BTC_USDT",
|
2829
|
+
// "tradedAmount": "0",
|
2830
|
+
// "triggerCondition": "<=",
|
2831
|
+
// "triggerPrice": "31000",
|
2832
|
+
// "triggerTime": "0",
|
2833
|
+
// "userId": "6896693805014120448"
|
2834
|
+
// },
|
2835
|
+
//
|
2836
|
+
// Spot createOrder
|
2837
|
+
//
|
2838
|
+
// {
|
2839
|
+
// code: '1000',
|
2840
|
+
// message: '操作成功',
|
2841
|
+
// id: '202202224851151555',
|
2842
|
+
// type: '1',
|
2843
|
+
// total_amount: 0.0002,
|
2844
|
+
// price: 30000
|
2845
|
+
// }
|
2846
|
+
//
|
2847
|
+
// Swap createOrder
|
2848
|
+
//
|
2849
|
+
// {
|
2850
|
+
// orderId: '6901786759944937472',
|
2851
|
+
// orderCode: null,
|
2852
|
+
// timeInForce: 'IOC',
|
2853
|
+
// total_amount: 0.0002,
|
2854
|
+
// price: 30000
|
2855
|
+
// }
|
2856
|
+
//
|
2857
|
+
// Algo createOrder
|
2858
|
+
//
|
2859
|
+
// {
|
2860
|
+
// "code": 10000,
|
2861
|
+
// "data": "6919884551305242624",
|
2862
|
+
// "desc": "操作成功"
|
2863
|
+
// }
|
2864
|
+
//
|
2865
|
+
let orderId = market['swap'] ? this.safeValue (order, 'orderId') : this.safeValue (order, 'id');
|
2866
|
+
if (orderId === undefined) {
|
2867
|
+
orderId = this.safeValue (order, 'id');
|
2868
|
+
}
|
2869
|
+
let side = this.safeInteger2 (order, 'type', 'side');
|
2870
|
+
if (side === undefined) {
|
2871
|
+
side = undefined;
|
2872
|
+
} else {
|
2873
|
+
if (market['type'] === 'spot') {
|
2874
|
+
side = (side === 1) ? 'buy' : 'sell';
|
2875
|
+
}
|
2876
|
+
}
|
2877
|
+
let timestamp = this.safeInteger (order, 'trade_date');
|
2878
|
+
if (timestamp === undefined) {
|
2879
|
+
timestamp = this.safeInteger (order, 'createTime');
|
2880
|
+
}
|
2881
|
+
const marketId = this.safeString (order, 'currency');
|
2882
|
+
market = this.safeMarket (marketId, market, '_');
|
2883
|
+
const price = this.safeString2 (order, 'price', 'algoPrice');
|
2884
|
+
const filled = market['swap'] ? this.safeString (order, 'tradeAmount') : this.safeString (order, 'trade_amount');
|
2885
|
+
let amount = this.safeString (order, 'total_amount');
|
2886
|
+
if (amount === undefined) {
|
2887
|
+
amount = this.safeString (order, 'amount');
|
2888
|
+
}
|
2889
|
+
const cost = this.safeString (order, 'trade_money');
|
2890
|
+
const status = this.parseOrderStatus (this.safeString (order, 'status'), market);
|
2891
|
+
const timeInForce = this.safeString (order, 'timeInForce');
|
2892
|
+
const postOnly = (timeInForce === 'PO');
|
2893
|
+
const feeCost = this.safeNumber (order, 'fees');
|
2894
|
+
let fee = undefined;
|
2895
|
+
if (feeCost !== undefined) {
|
2896
|
+
let feeCurrency = undefined;
|
2897
|
+
const zbFees = this.safeValue (order, 'useZbFee');
|
2898
|
+
if (zbFees === true) {
|
2899
|
+
feeCurrency = 'ZB';
|
2900
|
+
} else {
|
2901
|
+
feeCurrency = (side === 'sell') ? market['quote'] : market['base'];
|
2902
|
+
}
|
2903
|
+
fee = {
|
2904
|
+
'cost': feeCost,
|
2905
|
+
'currency': feeCurrency,
|
2906
|
+
};
|
2907
|
+
}
|
2908
|
+
return this.safeOrder ({
|
2909
|
+
'info': order,
|
2910
|
+
'id': orderId,
|
2911
|
+
'clientOrderId': this.safeString (order, 'userId'),
|
2912
|
+
'timestamp': timestamp,
|
2913
|
+
'datetime': this.iso8601 (timestamp),
|
2914
|
+
'lastTradeTimestamp': undefined,
|
2915
|
+
'symbol': market['symbol'],
|
2916
|
+
'type': 'limit', // market order is not available on ZB
|
2917
|
+
'timeInForce': timeInForce,
|
2918
|
+
'postOnly': postOnly,
|
2919
|
+
'side': side,
|
2920
|
+
'price': price,
|
2921
|
+
'stopPrice': this.safeString (order, 'triggerPrice'),
|
2922
|
+
'average': this.safeString (order, 'avgPrice'),
|
2923
|
+
'cost': cost,
|
2924
|
+
'amount': amount,
|
2925
|
+
'filled': filled,
|
2926
|
+
'remaining': undefined,
|
2927
|
+
'status': status,
|
2928
|
+
'fee': fee,
|
2929
|
+
'trades': undefined,
|
2930
|
+
}, market);
|
2931
|
+
}
|
2932
|
+
|
2933
|
+
parseOrderStatus (status, market = undefined) {
|
2934
|
+
let statuses = {};
|
2935
|
+
if (market['type'] === 'spot') {
|
2936
|
+
statuses = {
|
2937
|
+
'0': 'open',
|
2938
|
+
'1': 'canceled',
|
2939
|
+
'2': 'closed',
|
2940
|
+
'3': 'open', // partial
|
2941
|
+
};
|
2942
|
+
} else {
|
2943
|
+
statuses = {
|
2944
|
+
'1': 'open',
|
2945
|
+
'2': 'canceled',
|
2946
|
+
'3': 'open', // stop order triggered
|
2947
|
+
'4': 'failed',
|
2948
|
+
'5': 'closed',
|
2949
|
+
};
|
2950
|
+
}
|
2951
|
+
return this.safeString (statuses, status, status);
|
2952
|
+
}
|
2953
|
+
|
2954
|
+
parseTransactionStatus (status) {
|
2955
|
+
const statuses = {
|
2956
|
+
'0': 'pending', // submitted, pending confirmation
|
2957
|
+
'1': 'failed',
|
2958
|
+
'2': 'ok',
|
2959
|
+
'3': 'canceled',
|
2960
|
+
'5': 'ok', // confirmed
|
2961
|
+
};
|
2962
|
+
return this.safeString (statuses, status, status);
|
2963
|
+
}
|
2964
|
+
|
2965
|
+
parseTransaction (transaction, currency = undefined) {
|
2966
|
+
//
|
2967
|
+
// withdraw
|
2968
|
+
//
|
2969
|
+
// {
|
2970
|
+
// "code": 1000,
|
2971
|
+
// "message": "success",
|
2972
|
+
// "id": "withdrawalId"
|
2973
|
+
// }
|
2974
|
+
//
|
2975
|
+
// fetchWithdrawals
|
2976
|
+
//
|
2977
|
+
// {
|
2978
|
+
// "amount": 0.01,
|
2979
|
+
// "fees": 0.001,
|
2980
|
+
// "id": 2016042556231,
|
2981
|
+
// "manageTime": 1461579340000,
|
2982
|
+
// "status": 3,
|
2983
|
+
// "submitTime": 1461579288000,
|
2984
|
+
// "toAddress": "14fxEPirL9fyfw1i9EF439Pq6gQ5xijUmp",
|
2985
|
+
// }
|
2986
|
+
//
|
2987
|
+
// fetchDeposits
|
2988
|
+
//
|
2989
|
+
// {
|
2990
|
+
// "address": "1FKN1DZqCm8HaTujDioRL2Aezdh7Qj7xxx",
|
2991
|
+
// "amount": "1.00000000",
|
2992
|
+
// "confirmTimes": 1,
|
2993
|
+
// "currency": "BTC",
|
2994
|
+
// "description": "Successfully Confirm",
|
2995
|
+
// "hash": "7ce842de187c379abafadd64a5fe66c5c61c8a21fb04edff9532234a1dae6xxx",
|
2996
|
+
// "id": 558,
|
2997
|
+
// "itransfer": 1,
|
2998
|
+
// "status": 2,
|
2999
|
+
// "submit_time": "2016-12-07 18:51:57",
|
3000
|
+
// }
|
3001
|
+
//
|
3002
|
+
const id = this.safeString (transaction, 'id');
|
3003
|
+
const txid = this.safeString (transaction, 'hash');
|
3004
|
+
const amount = this.safeNumber (transaction, 'amount');
|
3005
|
+
let timestamp = this.parse8601 (this.safeString (transaction, 'submit_time'));
|
3006
|
+
timestamp = this.safeInteger (transaction, 'submitTime', timestamp);
|
3007
|
+
let address = this.safeString2 (transaction, 'toAddress', 'address');
|
3008
|
+
let tag = undefined;
|
3009
|
+
if (address !== undefined) {
|
3010
|
+
const parts = address.split ('_');
|
3011
|
+
address = this.safeString (parts, 0);
|
3012
|
+
tag = this.safeString (parts, 1);
|
3013
|
+
}
|
3014
|
+
const confirmTimes = this.safeInteger (transaction, 'confirmTimes');
|
3015
|
+
const updated = this.safeInteger (transaction, 'manageTime');
|
3016
|
+
let type = undefined;
|
3017
|
+
const currencyId = this.safeString (transaction, 'currency');
|
3018
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
3019
|
+
if (address !== undefined) {
|
3020
|
+
type = (confirmTimes === undefined) ? 'withdrawal' : 'deposit';
|
3021
|
+
}
|
3022
|
+
const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
|
3023
|
+
let fee = undefined;
|
3024
|
+
const feeCost = this.safeNumber (transaction, 'fees');
|
3025
|
+
if (feeCost !== undefined) {
|
3026
|
+
fee = {
|
3027
|
+
'cost': feeCost,
|
3028
|
+
'currency': code,
|
3029
|
+
};
|
3030
|
+
}
|
3031
|
+
return {
|
3032
|
+
'info': transaction,
|
3033
|
+
'id': id,
|
3034
|
+
'txid': txid,
|
3035
|
+
'timestamp': timestamp,
|
3036
|
+
'datetime': this.iso8601 (timestamp),
|
3037
|
+
'network': undefined,
|
3038
|
+
'addressFrom': undefined,
|
3039
|
+
'address': address,
|
3040
|
+
'addressTo': address,
|
3041
|
+
'tagFrom': undefined,
|
3042
|
+
'tag': tag,
|
3043
|
+
'tagTo': tag,
|
3044
|
+
'type': type,
|
3045
|
+
'amount': amount,
|
3046
|
+
'currency': code,
|
3047
|
+
'status': status,
|
3048
|
+
'updated': updated,
|
3049
|
+
'fee': fee,
|
3050
|
+
};
|
3051
|
+
}
|
3052
|
+
|
3053
|
+
async setLeverage (leverage, symbol = undefined, params = {}) {
|
3054
|
+
await this.loadMarkets ();
|
3055
|
+
if (symbol === undefined) {
|
3056
|
+
throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
|
3057
|
+
}
|
3058
|
+
if ((leverage < 1) || (leverage > 125)) {
|
3059
|
+
throw new BadRequest (this.id + ' setLeverage() leverage should be between 1 and 125');
|
3060
|
+
}
|
3061
|
+
const market = this.market (symbol);
|
3062
|
+
let accountType = undefined;
|
3063
|
+
if (!market['swap']) {
|
3064
|
+
throw new BadSymbol (this.id + ' setLeverage() supports swap contracts only');
|
3065
|
+
} else {
|
3066
|
+
accountType = 1;
|
3067
|
+
}
|
3068
|
+
const request = {
|
3069
|
+
'symbol': market['id'],
|
3070
|
+
'leverage': leverage,
|
3071
|
+
'futuresAccountType': accountType, // 1: USDT perpetual swaps
|
3072
|
+
};
|
3073
|
+
return await this.contractV2PrivatePostSettingSetLeverage (this.extend (request, params));
|
3074
|
+
}
|
3075
|
+
|
3076
|
+
async fetchFundingRateHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
3077
|
+
await this.loadMarkets ();
|
3078
|
+
const request = {
|
3079
|
+
// 'symbol': market['id'],
|
3080
|
+
// 'startTime': since,
|
3081
|
+
// 'endTime': endTime, // current time by default
|
3082
|
+
// 'limit': limit, // default 100, max 1000
|
3083
|
+
};
|
3084
|
+
if (symbol !== undefined) {
|
3085
|
+
const market = this.market (symbol);
|
3086
|
+
symbol = market['symbol'];
|
3087
|
+
request['symbol'] = market['id'];
|
3088
|
+
}
|
3089
|
+
if (since !== undefined) {
|
3090
|
+
request['startTime'] = since;
|
3091
|
+
}
|
3092
|
+
const till = this.safeInteger (params, 'till');
|
3093
|
+
const endTime = this.safeString (params, 'endTime');
|
3094
|
+
params = this.omit (params, [ 'endTime', 'till' ]);
|
3095
|
+
if (till !== undefined) {
|
3096
|
+
request['endTime'] = till;
|
3097
|
+
} else if (endTime !== undefined) {
|
3098
|
+
request['endTime'] = endTime;
|
3099
|
+
}
|
3100
|
+
if (limit !== undefined) {
|
3101
|
+
request['limit'] = limit;
|
3102
|
+
}
|
3103
|
+
const response = await this.contractV2PublicGetFundingRate (this.extend (request, params));
|
3104
|
+
//
|
3105
|
+
// {
|
3106
|
+
// "code": 10000,
|
3107
|
+
// "data": [
|
3108
|
+
// {
|
3109
|
+
// "symbol": "BTC_USDT",
|
3110
|
+
// "fundingRate": "0.0001",
|
3111
|
+
// "fundingTime": "1645171200000"
|
3112
|
+
// },
|
3113
|
+
// ],
|
3114
|
+
// "desc": "操作成功"
|
3115
|
+
// }
|
3116
|
+
//
|
3117
|
+
const data = this.safeValue (response, 'data');
|
3118
|
+
const rates = [];
|
3119
|
+
for (let i = 0; i < data.length; i++) {
|
3120
|
+
const entry = data[i];
|
3121
|
+
const marketId = this.safeString (entry, 'symbol');
|
3122
|
+
const symbol = this.safeSymbol (marketId);
|
3123
|
+
const timestamp = this.safeString (entry, 'fundingTime');
|
3124
|
+
rates.push ({
|
3125
|
+
'info': entry,
|
3126
|
+
'symbol': symbol,
|
3127
|
+
'fundingRate': this.safeNumber (entry, 'fundingRate'),
|
3128
|
+
'timestamp': timestamp,
|
3129
|
+
'datetime': this.iso8601 (timestamp),
|
3130
|
+
});
|
3131
|
+
}
|
3132
|
+
const sorted = this.sortBy (rates, 'timestamp');
|
3133
|
+
return this.filterBySymbolSinceLimit (sorted, symbol, since, limit);
|
3134
|
+
}
|
3135
|
+
|
3136
|
+
async fetchFundingRate (symbol, params = {}) {
|
3137
|
+
await this.loadMarkets ();
|
3138
|
+
const market = this.market (symbol);
|
3139
|
+
if (!market['swap']) {
|
3140
|
+
throw new BadSymbol (this.id + ' fetchFundingRate() does not supports contracts only');
|
3141
|
+
}
|
3142
|
+
const request = {
|
3143
|
+
'symbol': market['id'],
|
3144
|
+
};
|
3145
|
+
const response = await this.contractV1PublicGetFundingRate (this.extend (request, params));
|
3146
|
+
//
|
3147
|
+
// {
|
3148
|
+
// "code": 10000,
|
3149
|
+
// "desc": "操作成功",
|
3150
|
+
// "data": {
|
3151
|
+
// "fundingRate": "0.0001",
|
3152
|
+
// "nextCalculateTime": "2022-02-19 00:00:00"
|
3153
|
+
// }
|
3154
|
+
// }
|
3155
|
+
//
|
3156
|
+
const data = this.safeValue (response, 'data');
|
3157
|
+
return this.parseFundingRate (data, market);
|
3158
|
+
}
|
3159
|
+
|
3160
|
+
parseFundingRate (contract, market = undefined) {
|
3161
|
+
//
|
3162
|
+
// fetchFundingRate
|
3163
|
+
//
|
3164
|
+
// {
|
3165
|
+
// "fundingRate": "0.0001",
|
3166
|
+
// "nextCalculateTime": "2022-02-19 00:00:00"
|
3167
|
+
// }
|
3168
|
+
//
|
3169
|
+
// fetchFundingRates
|
3170
|
+
//
|
3171
|
+
// {
|
3172
|
+
// "symbol": "BTC_USDT",
|
3173
|
+
// "markPrice": "43254.42",
|
3174
|
+
// "indexPrice": "43278.61",
|
3175
|
+
// "lastFundingRate": "0.0001",
|
3176
|
+
// "nextFundingTime": "1646121600000"
|
3177
|
+
// }
|
3178
|
+
//
|
3179
|
+
const marketId = this.safeString (contract, 'symbol');
|
3180
|
+
const symbol = this.safeSymbol (marketId, market);
|
3181
|
+
const fundingRate = this.safeNumber (contract, 'fundingRate');
|
3182
|
+
const nextFundingDatetime = this.safeString (contract, 'nextCalculateTime');
|
3183
|
+
return {
|
3184
|
+
'info': contract,
|
3185
|
+
'symbol': symbol,
|
3186
|
+
'markPrice': this.safeString (contract, 'markPrice'),
|
3187
|
+
'indexPrice': this.safeString (contract, 'indexPrice'),
|
3188
|
+
'interestRate': undefined,
|
3189
|
+
'estimatedSettlePrice': undefined,
|
3190
|
+
'timestamp': undefined,
|
3191
|
+
'datetime': undefined,
|
3192
|
+
'fundingRate': fundingRate,
|
3193
|
+
'fundingTimestamp': undefined,
|
3194
|
+
'fundingDatetime': undefined,
|
3195
|
+
'nextFundingRate': undefined,
|
3196
|
+
'nextFundingTimestamp': this.parse8601 (nextFundingDatetime),
|
3197
|
+
'nextFundingDatetime': nextFundingDatetime,
|
3198
|
+
'previousFundingRate': this.safeString (contract, 'lastFundingRate'),
|
3199
|
+
'previousFundingTimestamp': undefined,
|
3200
|
+
'previousFundingDatetime': undefined,
|
3201
|
+
};
|
3202
|
+
}
|
3203
|
+
|
3204
|
+
async fetchFundingRates (symbols, params = {}) {
|
3205
|
+
await this.loadMarkets ();
|
3206
|
+
const response = await this.contractV2PublicGetPremiumIndex (params);
|
3207
|
+
//
|
3208
|
+
// {
|
3209
|
+
// "code": 10000,
|
3210
|
+
// "data": [
|
3211
|
+
// {
|
3212
|
+
// "symbol": "BTC_USDT",
|
3213
|
+
// "markPrice": "43254.42",
|
3214
|
+
// "indexPrice": "43278.61",
|
3215
|
+
// "lastFundingRate": "0.0001",
|
3216
|
+
// "nextFundingTime": "1646121600000"
|
3217
|
+
// },
|
3218
|
+
// ],
|
3219
|
+
// "desc":"操作成功"
|
3220
|
+
// }
|
3221
|
+
//
|
3222
|
+
const data = this.safeValue (response, 'data', []);
|
3223
|
+
const result = this.parseFundingRates (data);
|
3224
|
+
return this.filterByArray (result, 'symbol', symbols);
|
3225
|
+
}
|
3226
|
+
|
3227
|
+
async withdraw (code, amount, address, tag = undefined, params = {}) {
|
3228
|
+
[ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
|
3229
|
+
const password = this.safeString (params, 'safePwd', this.password);
|
3230
|
+
if (password === undefined) {
|
3231
|
+
throw new ArgumentsRequired (this.id + ' withdraw() requires exchange.password or a safePwd parameter');
|
3232
|
+
}
|
3233
|
+
const fees = this.safeNumber (params, 'fees');
|
3234
|
+
if (fees === undefined) {
|
3235
|
+
throw new ArgumentsRequired (this.id + ' withdraw() requires a fees parameter');
|
3236
|
+
}
|
3237
|
+
this.checkAddress (address);
|
3238
|
+
await this.loadMarkets ();
|
3239
|
+
const currency = this.currency (code);
|
3240
|
+
if (tag !== undefined) {
|
3241
|
+
address += '_' + tag;
|
3242
|
+
}
|
3243
|
+
const request = {
|
3244
|
+
'amount': this.currencyToPrecision (code, amount),
|
3245
|
+
'currency': currency['id'],
|
3246
|
+
'fees': this.currencyToPrecision (code, fees),
|
3247
|
+
// 'itransfer': 0, // agree for an internal transfer, 0 disagree, 1 agree, the default is to disagree
|
3248
|
+
'method': 'withdraw',
|
3249
|
+
'receiveAddr': address,
|
3250
|
+
'safePwd': password,
|
3251
|
+
};
|
3252
|
+
const response = await this.spotV1PrivateGetWithdraw (this.extend (request, params));
|
3253
|
+
//
|
3254
|
+
// {
|
3255
|
+
// "code": 1000,
|
3256
|
+
// "message": "success",
|
3257
|
+
// "id": "withdrawalId"
|
3258
|
+
// }
|
3259
|
+
//
|
3260
|
+
const transaction = this.parseTransaction (response, currency);
|
3261
|
+
return this.extend (transaction, {
|
3262
|
+
'type': 'withdrawal',
|
3263
|
+
'address': address,
|
3264
|
+
'addressTo': address,
|
3265
|
+
'amount': amount,
|
3266
|
+
});
|
3267
|
+
}
|
3268
|
+
|
3269
|
+
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
3270
|
+
await this.loadMarkets ();
|
3271
|
+
const request = {
|
3272
|
+
// 'currency': currency['id'],
|
3273
|
+
// 'pageIndex': 1,
|
3274
|
+
// 'pageSize': limit,
|
3275
|
+
};
|
3276
|
+
let currency = undefined;
|
3277
|
+
if (code !== undefined) {
|
3278
|
+
currency = this.currency (code);
|
3279
|
+
request['currency'] = currency['id'];
|
3280
|
+
}
|
3281
|
+
if (limit !== undefined) {
|
3282
|
+
request['pageSize'] = limit;
|
3283
|
+
}
|
3284
|
+
const response = await this.spotV1PrivateGetGetWithdrawRecord (this.extend (request, params));
|
3285
|
+
//
|
3286
|
+
// {
|
3287
|
+
// "code": 1000,
|
3288
|
+
// "message": {
|
3289
|
+
// "des": "success",
|
3290
|
+
// "isSuc": true,
|
3291
|
+
// "datas": {
|
3292
|
+
// "list": [
|
3293
|
+
// {
|
3294
|
+
// "amount": 0.01,
|
3295
|
+
// "fees": 0.001,
|
3296
|
+
// "id": 2016042556231,
|
3297
|
+
// "manageTime": 1461579340000,
|
3298
|
+
// "status": 3,
|
3299
|
+
// "submitTime": 1461579288000,
|
3300
|
+
// "toAddress": "14fxEPirL9fyfw1i9EF439Pq6gQ5xijUmp",
|
3301
|
+
// },
|
3302
|
+
// ],
|
3303
|
+
// "pageIndex": 1,
|
3304
|
+
// "pageSize": 10,
|
3305
|
+
// "totalCount": 4,
|
3306
|
+
// "totalPage": 1
|
3307
|
+
// }
|
3308
|
+
// }
|
3309
|
+
// }
|
3310
|
+
//
|
3311
|
+
const message = this.safeValue (response, 'message', {});
|
3312
|
+
const datas = this.safeValue (message, 'datas', {});
|
3313
|
+
const withdrawals = this.safeValue (datas, 'list', []);
|
3314
|
+
return this.parseTransactions (withdrawals, currency, since, limit);
|
3315
|
+
}
|
3316
|
+
|
3317
|
+
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
3318
|
+
await this.loadMarkets ();
|
3319
|
+
const request = {
|
3320
|
+
// 'currency': currency['id'],
|
3321
|
+
// 'pageIndex': 1,
|
3322
|
+
// 'pageSize': limit,
|
3323
|
+
};
|
3324
|
+
let currency = undefined;
|
3325
|
+
if (code !== undefined) {
|
3326
|
+
currency = this.currency (code);
|
3327
|
+
request['currency'] = currency['id'];
|
3328
|
+
}
|
3329
|
+
if (limit !== undefined) {
|
3330
|
+
request['pageSize'] = limit;
|
3331
|
+
}
|
3332
|
+
const response = await this.spotV1PrivateGetGetChargeRecord (this.extend (request, params));
|
3333
|
+
//
|
3334
|
+
// {
|
3335
|
+
// "code": 1000,
|
3336
|
+
// "message": {
|
3337
|
+
// "des": "success",
|
3338
|
+
// "isSuc": true,
|
3339
|
+
// "datas": {
|
3340
|
+
// "list": [
|
3341
|
+
// {
|
3342
|
+
// "address": "1FKN1DZqCm8HaTujDioRL2Aezdh7Qj7xxx",
|
3343
|
+
// "amount": "1.00000000",
|
3344
|
+
// "confirmTimes": 1,
|
3345
|
+
// "currency": "BTC",
|
3346
|
+
// "description": "Successfully Confirm",
|
3347
|
+
// "hash": "7ce842de187c379abafadd64a5fe66c5c61c8a21fb04edff9532234a1dae6xxx",
|
3348
|
+
// "id": 558,
|
3349
|
+
// "itransfer": 1,
|
3350
|
+
// "status": 2,
|
3351
|
+
// "submit_time": "2016-12-07 18:51:57",
|
3352
|
+
// },
|
3353
|
+
// ],
|
3354
|
+
// "pageIndex": 1,
|
3355
|
+
// "pageSize": 10,
|
3356
|
+
// "total": 8
|
3357
|
+
// }
|
3358
|
+
// }
|
3359
|
+
// }
|
3360
|
+
//
|
3361
|
+
const message = this.safeValue (response, 'message', {});
|
3362
|
+
const datas = this.safeValue (message, 'datas', {});
|
3363
|
+
const deposits = this.safeValue (datas, 'list', []);
|
3364
|
+
return this.parseTransactions (deposits, currency, since, limit);
|
3365
|
+
}
|
3366
|
+
|
3367
|
+
async fetchPosition (symbol, params = {}) {
|
3368
|
+
await this.loadMarkets ();
|
3369
|
+
let market = undefined;
|
3370
|
+
if (symbol !== undefined) {
|
3371
|
+
market = this.market (symbol);
|
3372
|
+
}
|
3373
|
+
const request = {
|
3374
|
+
'futuresAccountType': 1, // 1: USDT-M Perpetual Futures
|
3375
|
+
// 'symbol': market['id'],
|
3376
|
+
// 'marketId': market['id'],
|
3377
|
+
// 'side': params['side'],
|
3378
|
+
};
|
3379
|
+
const response = await this.contractV2PrivateGetPositionsGetPositions (this.extend (request, params));
|
3380
|
+
//
|
3381
|
+
// {
|
3382
|
+
// "code": 10000,
|
3383
|
+
// "data": [
|
3384
|
+
// {
|
3385
|
+
// "amount": "0.002",
|
3386
|
+
// "appendAmount": "0",
|
3387
|
+
// "autoLightenRatio": "0",
|
3388
|
+
// "avgPrice": "38570",
|
3389
|
+
// "bankruptcyPrice": "46288.41",
|
3390
|
+
// "contractType": 1,
|
3391
|
+
// "createTime": "1645784751867",
|
3392
|
+
// "freezeAmount": "0",
|
3393
|
+
// "freezeList": [
|
3394
|
+
// {
|
3395
|
+
// "amount": "15.436832",
|
3396
|
+
// "currencyId": "6",
|
3397
|
+
// "currencyName": "usdt",
|
3398
|
+
// "modifyTime": "1645784751867"
|
3399
|
+
// }
|
3400
|
+
// ],
|
3401
|
+
// "id": "6902921567894972486",
|
3402
|
+
// "lastAppendAmount": "0",
|
3403
|
+
// "leverage": 5,
|
3404
|
+
// "liquidateLevel": 1,
|
3405
|
+
// "liquidatePrice": "46104",
|
3406
|
+
// "maintainMargin": "0.30912384",
|
3407
|
+
// "margin": "15.436832",
|
3408
|
+
// "marginAppendCount": 0,
|
3409
|
+
// "marginBalance": "15.295872",
|
3410
|
+
// "marginMode": 1,
|
3411
|
+
// "marginRate": "0.020209",
|
3412
|
+
// "marketId": "100",
|
3413
|
+
// "marketName": "BTC_USDT",
|
3414
|
+
// "modifyTime": "1645784751867",
|
3415
|
+
// "nominalValue": "77.14736",
|
3416
|
+
// "originAppendAmount": "0",
|
3417
|
+
// "originId": "6902921567894972591",
|
3418
|
+
// "refreshType": "Timer",
|
3419
|
+
// "returnRate": "-0.0091",
|
3420
|
+
// "side": 0,
|
3421
|
+
// "status": 1,
|
3422
|
+
// "unrealizedPnl": "-0.14096",
|
3423
|
+
// "userId": "6896693805014120448"
|
3424
|
+
// }
|
3425
|
+
// ],
|
3426
|
+
// "desc": "操作成功"
|
3427
|
+
// }
|
3428
|
+
//
|
3429
|
+
const data = this.safeValue (response, 'data', []);
|
3430
|
+
const firstPosition = this.safeValue (data, 0);
|
3431
|
+
return this.parsePosition (firstPosition, market);
|
3432
|
+
}
|
3433
|
+
|
3434
|
+
async fetchPositions (symbols = undefined, params = {}) {
|
3435
|
+
await this.loadMarkets ();
|
3436
|
+
let market = undefined;
|
3437
|
+
if (symbols !== undefined) {
|
3438
|
+
market = this.market (symbols);
|
3439
|
+
}
|
3440
|
+
const request = {
|
3441
|
+
'futuresAccountType': 1, // 1: USDT-M Perpetual Futures
|
3442
|
+
// 'symbol': market['id'],
|
3443
|
+
// 'marketId': market['id'],
|
3444
|
+
// 'side': params['side'],
|
3445
|
+
};
|
3446
|
+
const response = await this.contractV2PrivateGetPositionsGetPositions (this.extend (request, params));
|
3447
|
+
//
|
3448
|
+
// {
|
3449
|
+
// "code": 10000,
|
3450
|
+
// "data": [
|
3451
|
+
// {
|
3452
|
+
// "amount": "0.002",
|
3453
|
+
// "appendAmount": "0",
|
3454
|
+
// "autoLightenRatio": "0",
|
3455
|
+
// "avgPrice": "38570",
|
3456
|
+
// "bankruptcyPrice": "46288.41",
|
3457
|
+
// "contractType": 1,
|
3458
|
+
// "createTime": "1645784751867",
|
3459
|
+
// "freezeAmount": "0",
|
3460
|
+
// "freezeList": [
|
3461
|
+
// {
|
3462
|
+
// "amount": "15.436832",
|
3463
|
+
// "currencyId": "6",
|
3464
|
+
// "currencyName": "usdt",
|
3465
|
+
// "modifyTime": "1645784751867"
|
3466
|
+
// }
|
3467
|
+
// ],
|
3468
|
+
// "id": "6902921567894972486",
|
3469
|
+
// "lastAppendAmount": "0",
|
3470
|
+
// "leverage": 5,
|
3471
|
+
// "liquidateLevel": 1,
|
3472
|
+
// "liquidatePrice": "46104",
|
3473
|
+
// "maintainMargin": "0.30912384",
|
3474
|
+
// "margin": "15.436832",
|
3475
|
+
// "marginAppendCount": 0,
|
3476
|
+
// "marginBalance": "15.295872",
|
3477
|
+
// "marginMode": 1,
|
3478
|
+
// "marginRate": "0.020209",
|
3479
|
+
// "marketId": "100",
|
3480
|
+
// "marketName": "BTC_USDT",
|
3481
|
+
// "modifyTime": "1645784751867",
|
3482
|
+
// "nominalValue": "77.14736",
|
3483
|
+
// "originAppendAmount": "0",
|
3484
|
+
// "originId": "6902921567894972591",
|
3485
|
+
// "refreshType": "Timer",
|
3486
|
+
// "returnRate": "-0.0091",
|
3487
|
+
// "side": 0,
|
3488
|
+
// "status": 1,
|
3489
|
+
// "unrealizedPnl": "-0.14096",
|
3490
|
+
// "userId": "6896693805014120448"
|
3491
|
+
// },
|
3492
|
+
// ],
|
3493
|
+
// "desc": "操作成功"
|
3494
|
+
// }
|
3495
|
+
//
|
3496
|
+
const data = this.safeValue (response, 'data', []);
|
3497
|
+
return this.parsePositions (data, market);
|
3498
|
+
}
|
3499
|
+
|
3500
|
+
parsePosition (position, market = undefined) {
|
3501
|
+
//
|
3502
|
+
// {
|
3503
|
+
// "amount": "0.002",
|
3504
|
+
// "appendAmount": "0",
|
3505
|
+
// "autoLightenRatio": "0",
|
3506
|
+
// "avgPrice": "38570",
|
3507
|
+
// "bankruptcyPrice": "46288.41",
|
3508
|
+
// "contractType": 1,
|
3509
|
+
// "createTime": "1645784751867",
|
3510
|
+
// "freezeAmount": "0",
|
3511
|
+
// "freezeList": [
|
3512
|
+
// {
|
3513
|
+
// "amount": "15.436832",
|
3514
|
+
// "currencyId": "6",
|
3515
|
+
// "currencyName": "usdt",
|
3516
|
+
// "modifyTime": "1645784751867"
|
3517
|
+
// }
|
3518
|
+
// ],
|
3519
|
+
// "id": "6902921567894972486",
|
3520
|
+
// "lastAppendAmount": "0",
|
3521
|
+
// "leverage": 5,
|
3522
|
+
// "liquidateLevel": 1,
|
3523
|
+
// "liquidatePrice": "46104",
|
3524
|
+
// "maintainMargin": "0.30912384",
|
3525
|
+
// "margin": "15.436832",
|
3526
|
+
// "marginAppendCount": 0,
|
3527
|
+
// "marginBalance": "15.295872",
|
3528
|
+
// "marginMode": 1,
|
3529
|
+
// "marginRate": "0.020209",
|
3530
|
+
// "marketId": "100",
|
3531
|
+
// "marketName": "BTC_USDT",
|
3532
|
+
// "modifyTime": "1645784751867",
|
3533
|
+
// "nominalValue": "77.14736",
|
3534
|
+
// "originAppendAmount": "0",
|
3535
|
+
// "originId": "6902921567894972591",
|
3536
|
+
// "refreshType": "Timer",
|
3537
|
+
// "returnRate": "-0.0091",
|
3538
|
+
// "side": 0,
|
3539
|
+
// "status": 1,
|
3540
|
+
// "unrealizedPnl": "-0.14096",
|
3541
|
+
// "userId": "6896693805014120448"
|
3542
|
+
// }
|
3543
|
+
//
|
3544
|
+
market = this.safeMarket (this.safeString (position, 'marketName'), market);
|
3545
|
+
const symbol = market['symbol'];
|
3546
|
+
const contracts = this.safeString (position, 'amount');
|
3547
|
+
const entryPrice = this.safeNumber (position, 'avgPrice');
|
3548
|
+
const initialMargin = this.safeString (position, 'margin');
|
3549
|
+
const rawSide = this.safeString (position, 'side');
|
3550
|
+
const side = (rawSide === '1') ? 'long' : 'short';
|
3551
|
+
const openType = this.safeString (position, 'marginMode');
|
3552
|
+
const marginType = (openType === '1') ? 'isolated' : 'cross';
|
3553
|
+
const leverage = this.safeString (position, 'leverage');
|
3554
|
+
const liquidationPrice = this.safeNumber (position, 'liquidatePrice');
|
3555
|
+
const unrealizedProfit = this.safeNumber (position, 'unrealizedPnl');
|
3556
|
+
const maintenanceMargin = this.safeNumber (position, 'maintainMargin');
|
3557
|
+
const marginRatio = this.safeNumber (position, 'marginRate');
|
3558
|
+
const notional = this.safeNumber (position, 'nominalValue');
|
3559
|
+
const percentage = Precise.stringMul (this.safeString (position, 'returnRate'), '100');
|
3560
|
+
const timestamp = this.safeNumber (position, 'createTime');
|
3561
|
+
return {
|
3562
|
+
'info': position,
|
3563
|
+
'symbol': symbol,
|
3564
|
+
'contracts': this.parseNumber (contracts),
|
3565
|
+
'contractSize': undefined,
|
3566
|
+
'entryPrice': entryPrice,
|
3567
|
+
'collateral': undefined,
|
3568
|
+
'side': side,
|
3569
|
+
'unrealizedProfit': unrealizedProfit,
|
3570
|
+
'leverage': this.parseNumber (leverage),
|
3571
|
+
'percentage': percentage,
|
3572
|
+
'marginType': marginType,
|
3573
|
+
'notional': notional,
|
3574
|
+
'markPrice': undefined,
|
3575
|
+
'liquidationPrice': liquidationPrice,
|
3576
|
+
'initialMargin': this.parseNumber (initialMargin),
|
3577
|
+
'initialMarginPercentage': undefined,
|
3578
|
+
'maintenanceMargin': maintenanceMargin,
|
3579
|
+
'maintenanceMarginPercentage': undefined,
|
3580
|
+
'marginRatio': marginRatio,
|
3581
|
+
'timestamp': timestamp,
|
3582
|
+
'datetime': this.iso8601 (timestamp),
|
3583
|
+
};
|
3584
|
+
}
|
3585
|
+
|
3586
|
+
parsePositions (positions) {
|
3587
|
+
const result = [];
|
3588
|
+
for (let i = 0; i < positions.length; i++) {
|
3589
|
+
result.push (this.parsePosition (positions[i]));
|
3590
|
+
}
|
3591
|
+
return result;
|
3592
|
+
}
|
3593
|
+
|
3594
|
+
parseLedgerEntryType (type) {
|
3595
|
+
const types = {
|
3596
|
+
'1': 'realized pnl',
|
3597
|
+
'2': 'commission',
|
3598
|
+
'3': 'funding fee subtract',
|
3599
|
+
'4': 'funding fee addition',
|
3600
|
+
'5': 'insurance clear',
|
3601
|
+
'6': 'transfer in',
|
3602
|
+
'7': 'transfer out',
|
3603
|
+
'8': 'margin addition',
|
3604
|
+
'9': 'margin subtraction',
|
3605
|
+
'10': 'commission addition',
|
3606
|
+
'11': 'bill type freeze',
|
3607
|
+
'12': 'bill type unfreeze',
|
3608
|
+
'13': 'system take over margin',
|
3609
|
+
'14': 'transfer',
|
3610
|
+
'15': 'realized pnl collection',
|
3611
|
+
'16': 'funding fee collection',
|
3612
|
+
'17': 'recommender return commission',
|
3613
|
+
'18': 'by level subtract positions',
|
3614
|
+
'19': 'system add',
|
3615
|
+
'20': 'system subtract',
|
3616
|
+
'23': 'trading competition take over fund',
|
3617
|
+
'24': 'trading contest tickets',
|
3618
|
+
'25': 'return of trading contest tickets',
|
3619
|
+
'26': 'experience expired recall',
|
3620
|
+
'50': 'test register gift',
|
3621
|
+
'51': 'register gift',
|
3622
|
+
'52': 'deposit gift',
|
3623
|
+
'53': 'trading volume gift',
|
3624
|
+
'54': 'awards gift',
|
3625
|
+
'55': 'trading volume gift',
|
3626
|
+
'56': 'awards gift expire',
|
3627
|
+
'201': 'open positions',
|
3628
|
+
'202': 'close positions',
|
3629
|
+
'203': 'take over positions',
|
3630
|
+
'204': 'trading competition take over positions',
|
3631
|
+
'205': 'one way open long',
|
3632
|
+
'206': 'one way open short',
|
3633
|
+
'207': 'one way close long',
|
3634
|
+
'208': 'one way close short',
|
3635
|
+
'301': 'coupon deduction service charge',
|
3636
|
+
'302': 'experience deduction',
|
3637
|
+
'303': 'experience expired',
|
3638
|
+
};
|
3639
|
+
return this.safeString (types, type, type);
|
3640
|
+
}
|
3641
|
+
|
3642
|
+
parseLedgerEntry (item, currency = undefined) {
|
3643
|
+
//
|
3644
|
+
// [
|
3645
|
+
// {
|
3646
|
+
// "type": 3,
|
3647
|
+
// "changeAmount": "0.00434664",
|
3648
|
+
// "isIn": 0,
|
3649
|
+
// "beforeAmount": "30.53353135",
|
3650
|
+
// "beforeFreezeAmount": "21.547",
|
3651
|
+
// "createTime": "1646121604997",
|
3652
|
+
// "available": "30.52918471",
|
3653
|
+
// "unit": "usdt",
|
3654
|
+
// "symbol": "BTC_USDT"
|
3655
|
+
// },
|
3656
|
+
// ],
|
3657
|
+
//
|
3658
|
+
const timestamp = this.safeString (item, 'createTime');
|
3659
|
+
let direction = undefined;
|
3660
|
+
const changeDirection = this.safeNumber (item, 'isIn');
|
3661
|
+
if (changeDirection === 1) {
|
3662
|
+
direction = 'increase';
|
3663
|
+
} else {
|
3664
|
+
direction = 'reduce';
|
3665
|
+
}
|
3666
|
+
let fee = undefined;
|
3667
|
+
const feeCost = this.safeNumber (item, 'fee');
|
3668
|
+
if (feeCost !== undefined) {
|
3669
|
+
fee = {
|
3670
|
+
'cost': feeCost,
|
3671
|
+
'currency': this.safeCurrencyCode (this.safeString (item, 'unit')),
|
3672
|
+
};
|
3673
|
+
}
|
3674
|
+
return {
|
3675
|
+
'id': this.safeString (item, 'id'),
|
3676
|
+
'info': item,
|
3677
|
+
'timestamp': timestamp,
|
3678
|
+
'datetime': this.iso8601 (timestamp),
|
3679
|
+
'direction': direction,
|
3680
|
+
'account': this.safeString (item, 'userId'),
|
3681
|
+
'referenceId': undefined,
|
3682
|
+
'referenceAccount': undefined,
|
3683
|
+
'type': this.parseLedgerEntryType (this.safeInteger (item, 'type')),
|
3684
|
+
'currency': this.safeCurrencyCode (this.safeString (item, 'unit')),
|
3685
|
+
'amount': this.safeNumber (item, 'changeAmount'),
|
3686
|
+
'before': this.safeNumber (item, 'beforeAmount'),
|
3687
|
+
'after': this.safeNumber (item, 'available'),
|
3688
|
+
'status': undefined,
|
3689
|
+
'fee': fee,
|
3690
|
+
};
|
3691
|
+
}
|
3692
|
+
|
3693
|
+
async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
|
3694
|
+
if (code === undefined) {
|
3695
|
+
throw new ArgumentsRequired (this.id + ' fetchLedger() requires a code argument');
|
3696
|
+
}
|
3697
|
+
await this.loadMarkets ();
|
3698
|
+
const currency = this.currency (code);
|
3699
|
+
const request = {
|
3700
|
+
'futuresAccountType': 1,
|
3701
|
+
// 'currencyId': '11',
|
3702
|
+
// 'type': 1,
|
3703
|
+
// 'endTime': this.milliseconds (),
|
3704
|
+
// 'pageNum': 1,
|
3705
|
+
};
|
3706
|
+
if (code !== undefined) {
|
3707
|
+
request['currencyName'] = currency['id'];
|
3708
|
+
}
|
3709
|
+
if (since !== undefined) {
|
3710
|
+
request['startTime'] = since;
|
3711
|
+
}
|
3712
|
+
if (limit !== undefined) {
|
3713
|
+
request['pageSize'] = limit;
|
3714
|
+
}
|
3715
|
+
const response = await this.contractV2PrivateGetFundGetBill (this.extend (request, params));
|
3716
|
+
//
|
3717
|
+
// {
|
3718
|
+
// "code": 10000,
|
3719
|
+
// "data": {
|
3720
|
+
// "list": [
|
3721
|
+
// {
|
3722
|
+
// "type": 3,
|
3723
|
+
// "changeAmount": "0.00434664",
|
3724
|
+
// "isIn": 0,
|
3725
|
+
// "beforeAmount": "30.53353135",
|
3726
|
+
// "beforeFreezeAmount": "21.547",
|
3727
|
+
// "createTime": "1646121604997",
|
3728
|
+
// "available": "30.52918471",
|
3729
|
+
// "unit": "usdt",
|
3730
|
+
// "symbol": "BTC_USDT"
|
3731
|
+
// },
|
3732
|
+
// ],
|
3733
|
+
// "pageNum": 1,
|
3734
|
+
// "pageSize": 10
|
3735
|
+
// },
|
3736
|
+
// "desc": "操作成功"
|
3737
|
+
// }
|
3738
|
+
//
|
3739
|
+
const data = this.safeValue (response, 'data', {});
|
3740
|
+
const list = this.safeValue (data, 'list', []);
|
3741
|
+
return this.parseLedger (list, currency, since, limit);
|
3742
|
+
}
|
3743
|
+
|
3744
|
+
async transfer (code, amount, fromAccount, toAccount, params = {}) {
|
3745
|
+
await this.loadMarkets ();
|
3746
|
+
const [ marketType, query ] = this.handleMarketTypeAndParams ('transfer', undefined, params);
|
3747
|
+
const currency = this.currency (code);
|
3748
|
+
const margin = (marketType === 'margin');
|
3749
|
+
const swap = (marketType === 'swap');
|
3750
|
+
let side = undefined;
|
3751
|
+
let marginMethod = undefined;
|
3752
|
+
const amountToPrecision = this.currencyToPrecision (code, amount);
|
3753
|
+
const request = {
|
3754
|
+
'amount': amountToPrecision, // Swap, Cross Margin, Isolated Margin
|
3755
|
+
// 'coin': currency['id'], // Margin
|
3756
|
+
// 'currencyName': currency['id'], // Swap
|
3757
|
+
// 'clientId': this.safeString (params, 'clientId'), // Swap "2sdfsdfsdf232342"
|
3758
|
+
// 'side': side, // Swap, 1:Deposit (zb account -> futures account),0:Withdrawal (futures account -> zb account)
|
3759
|
+
// 'marketName': this.safeString (params, 'marketName'), // Isolated Margin
|
3760
|
+
};
|
3761
|
+
if (swap) {
|
3762
|
+
if (fromAccount === 'spot' || toAccount === 'future') {
|
3763
|
+
side = 1;
|
3764
|
+
} else {
|
3765
|
+
side = 0;
|
3766
|
+
}
|
3767
|
+
request['currencyName'] = currency['id'];
|
3768
|
+
request['clientId'] = this.safeString (params, 'clientId');
|
3769
|
+
request['side'] = side;
|
3770
|
+
} else {
|
3771
|
+
const defaultMargin = margin ? 'isolated' : 'cross';
|
3772
|
+
const marginType = this.safeString2 (this.options, 'defaultMarginType', 'marginType', defaultMargin);
|
3773
|
+
if (marginType === 'isolated') {
|
3774
|
+
if (fromAccount === 'spot' || toAccount === 'isolated') {
|
3775
|
+
marginMethod = 'spotV1PrivateGetTransferInLever';
|
3776
|
+
} else {
|
3777
|
+
marginMethod = 'spotV1PrivateGetTransferOutLever';
|
3778
|
+
}
|
3779
|
+
request['marketName'] = this.safeString (params, 'marketName');
|
3780
|
+
} else if (marginType === 'cross') {
|
3781
|
+
if (fromAccount === 'spot' || toAccount === 'cross') {
|
3782
|
+
marginMethod = 'spotV1PrivateGetTransferInCross';
|
3783
|
+
} else {
|
3784
|
+
marginMethod = 'spotV1PrivateGetTransferOutCross';
|
3785
|
+
}
|
3786
|
+
}
|
3787
|
+
request['coin'] = currency['id'];
|
3788
|
+
}
|
3789
|
+
const method = this.getSupportedMapping (marketType, {
|
3790
|
+
'swap': 'contractV2PrivatePostFundTransferFund',
|
3791
|
+
'margin': marginMethod,
|
3792
|
+
});
|
3793
|
+
const response = await this[method] (this.extend (request, query));
|
3794
|
+
//
|
3795
|
+
// Swap
|
3796
|
+
//
|
3797
|
+
// {
|
3798
|
+
// "code": 10000,
|
3799
|
+
// "data": "2sdfsdfsdf232342",
|
3800
|
+
// "desc": "Success"
|
3801
|
+
// }
|
3802
|
+
//
|
3803
|
+
// Margin
|
3804
|
+
//
|
3805
|
+
// {
|
3806
|
+
// "code": 1000,
|
3807
|
+
// "message": "Success"
|
3808
|
+
// }
|
3809
|
+
//
|
3810
|
+
return this.extend (this.parseTransfer (response, currency), {
|
3811
|
+
'amount': this.parseNumber (amountToPrecision),
|
3812
|
+
'fromAccount': fromAccount,
|
3813
|
+
'toAccount': toAccount,
|
3814
|
+
});
|
3815
|
+
}
|
3816
|
+
|
3817
|
+
parseTransfer (transfer, currency = undefined) {
|
3818
|
+
// response samples in 'transfer'
|
3819
|
+
const timestamp = this.milliseconds ();
|
3820
|
+
return {
|
3821
|
+
'id': this.safeString (transfer, 'data'),
|
3822
|
+
'timestamp': timestamp,
|
3823
|
+
'datetime': this.iso8601 (timestamp),
|
3824
|
+
'currency': this.safeCurrencyCode (undefined, 'currency'),
|
3825
|
+
'amount': undefined,
|
3826
|
+
'fromAccount': undefined,
|
3827
|
+
'toAccount': undefined,
|
3828
|
+
'status': undefined,
|
3829
|
+
};
|
3830
|
+
}
|
3831
|
+
|
3832
|
+
async modifyMarginHelper (symbol, amount, type, params = {}) {
|
3833
|
+
if (params['positionsId'] === undefined) {
|
3834
|
+
throw new ArgumentsRequired (this.id + ' modifyMarginHelper() requires a positionsId argument in the params');
|
3835
|
+
}
|
3836
|
+
await this.loadMarkets ();
|
3837
|
+
const market = this.market (symbol);
|
3838
|
+
amount = this.amountToPrecision (symbol, amount);
|
3839
|
+
const position = this.safeString (params, 'positionsId');
|
3840
|
+
const request = {
|
3841
|
+
'positionsId': position,
|
3842
|
+
'amount': amount,
|
3843
|
+
'type': type, // 1 increase, 0 reduce
|
3844
|
+
'futuresAccountType': 1, // 1: USDT Perpetual Futures
|
3845
|
+
};
|
3846
|
+
const response = await this.contractV2PrivatePostPositionsUpdateMargin (this.extend (request, params));
|
3847
|
+
//
|
3848
|
+
// {
|
3849
|
+
// "code": 10000,
|
3850
|
+
// "data": {
|
3851
|
+
// "amount": "0.002",
|
3852
|
+
// "appendAmount": "0",
|
3853
|
+
// "avgPrice": "43927.23",
|
3854
|
+
// "bankruptcyPrice": "41730.86",
|
3855
|
+
// "createTime": "1646208695609",
|
3856
|
+
// "freezeAmount": "0",
|
3857
|
+
// "id": "6900781818669377576",
|
3858
|
+
// "keyMark": "6896693805014120448-100-1-",
|
3859
|
+
// "lastAppendAmount": "0",
|
3860
|
+
// "lastTime": "1646209235505",
|
3861
|
+
// "leverage": 20,
|
3862
|
+
// "liquidateLevel": 1,
|
3863
|
+
// "liquidatePrice": "41898.46",
|
3864
|
+
// "maintainMargin": "0",
|
3865
|
+
// "margin": "4.392723",
|
3866
|
+
// "marginAppendCount": 0,
|
3867
|
+
// "marginBalance": "0",
|
3868
|
+
// "marginMode": 1,
|
3869
|
+
// "marginRate": "0",
|
3870
|
+
// "marketId": "100",
|
3871
|
+
// "marketName": "BTC_USDT",
|
3872
|
+
// "modifyTime": "1646209235505",
|
3873
|
+
// "nominalValue": "87.88828",
|
3874
|
+
// "originAppendAmount": "0",
|
3875
|
+
// "originId": "6904699716827818029",
|
3876
|
+
// "positionsMode": 2,
|
3877
|
+
// "sellerCurrencyId": "1",
|
3878
|
+
// "side": 1,
|
3879
|
+
// "status": 1,
|
3880
|
+
// "unrealizedPnl": "0.03382",
|
3881
|
+
// "usable": true,
|
3882
|
+
// "userId": "6896693805014120448"
|
3883
|
+
// },
|
3884
|
+
// "desc":"操作成功"
|
3885
|
+
// }
|
3886
|
+
//
|
3887
|
+
return this.extend (this.parseModifyMargin (response, market), {
|
3888
|
+
'amount': this.parseNumber (amount),
|
3889
|
+
});
|
3890
|
+
}
|
3891
|
+
|
3892
|
+
parseModifyMargin (data, market = undefined) {
|
3893
|
+
const innerData = this.safeValue (data, 'data', {});
|
3894
|
+
const sideRaw = this.safeInteger (innerData, 'side');
|
3895
|
+
const side = (sideRaw === 1) ? 'add' : 'reduce';
|
3896
|
+
const statusCode = this.safeInteger (innerData, 'status');
|
3897
|
+
const status = (statusCode === 1) ? 'ok' : 'failed';
|
3898
|
+
return {
|
3899
|
+
'info': data,
|
3900
|
+
'type': side,
|
3901
|
+
'amount': undefined,
|
3902
|
+
'code': market['quote'],
|
3903
|
+
'symbol': market['symbol'],
|
3904
|
+
'status': status,
|
3905
|
+
};
|
3906
|
+
}
|
3907
|
+
|
3908
|
+
async addMargin (symbol, amount, params = {}) {
|
3909
|
+
if (params['positionsId'] === undefined) {
|
3910
|
+
throw new ArgumentsRequired (this.id + ' addMargin() requires a positionsId argument in the params');
|
3911
|
+
}
|
3912
|
+
return await this.modifyMarginHelper (symbol, amount, 1, params);
|
3913
|
+
}
|
3914
|
+
|
3915
|
+
async reduceMargin (symbol, amount, params = {}) {
|
3916
|
+
if (params['positionsId'] === undefined) {
|
3917
|
+
throw new ArgumentsRequired (this.id + ' reduceMargin() requires a positionsId argument in the params');
|
3918
|
+
}
|
3919
|
+
return await this.modifyMarginHelper (symbol, amount, 0, params);
|
3920
|
+
}
|
3921
|
+
|
3922
|
+
async fetchBorrowRate (code, params = {}) {
|
3923
|
+
await this.loadMarkets ();
|
3924
|
+
const currency = this.currency (code);
|
3925
|
+
const request = {
|
3926
|
+
'coin': currency['id'],
|
3927
|
+
};
|
3928
|
+
const response = await this.spotV1PrivateGetGetLoans (this.extend (request, params));
|
3929
|
+
//
|
3930
|
+
// {
|
3931
|
+
// code: '1000',
|
3932
|
+
// message: '操作成功',
|
3933
|
+
// result: [
|
3934
|
+
// {
|
3935
|
+
// interestRateOfDay: '0.0005',
|
3936
|
+
// repaymentDay: '30',
|
3937
|
+
// amount: '148804.4841',
|
3938
|
+
// balance: '148804.4841',
|
3939
|
+
// rateOfDayShow: '0.05 %',
|
3940
|
+
// coinName: 'USDT',
|
3941
|
+
// lowestAmount: '0.01'
|
3942
|
+
// },
|
3943
|
+
// ]
|
3944
|
+
// }
|
3945
|
+
//
|
3946
|
+
const timestamp = this.milliseconds ();
|
3947
|
+
const data = this.safeValue (response, 'result', []);
|
3948
|
+
const rate = this.safeValue (data, 0, {});
|
3949
|
+
return {
|
3950
|
+
'currency': this.safeCurrencyCode (this.safeString (rate, 'coinName')),
|
3951
|
+
'rate': this.safeNumber (rate, 'interestRateOfDay'),
|
3952
|
+
'period': this.safeNumber (rate, 'repaymentDay'),
|
3953
|
+
'timestamp': timestamp,
|
3954
|
+
'datetime': this.iso8601 (timestamp),
|
3955
|
+
'info': rate,
|
3956
|
+
};
|
3957
|
+
}
|
3958
|
+
|
3959
|
+
async fetchBorrowRates (params = {}) {
|
3960
|
+
if (params['coin'] === undefined) {
|
3961
|
+
throw new ArgumentsRequired (this.id + ' fetchBorrowRates() requires a coin argument in the params');
|
3962
|
+
}
|
3963
|
+
await this.loadMarkets ();
|
3964
|
+
const currency = this.currency (this.safeString (params, 'coin'));
|
3965
|
+
const request = {
|
3966
|
+
'coin': currency['id'],
|
3967
|
+
};
|
3968
|
+
const response = await this.spotV1PrivateGetGetLoans (this.extend (request, params));
|
3969
|
+
//
|
3970
|
+
// {
|
3971
|
+
// code: '1000',
|
3972
|
+
// message: '操作成功',
|
3973
|
+
// result: [
|
3974
|
+
// {
|
3975
|
+
// interestRateOfDay: '0.0005',
|
3976
|
+
// repaymentDay: '30',
|
3977
|
+
// amount: '148804.4841',
|
3978
|
+
// balance: '148804.4841',
|
3979
|
+
// rateOfDayShow: '0.05 %',
|
3980
|
+
// coinName: 'USDT',
|
3981
|
+
// lowestAmount: '0.01'
|
3982
|
+
// },
|
3983
|
+
// ]
|
3984
|
+
// }
|
3985
|
+
//
|
3986
|
+
const timestamp = this.milliseconds ();
|
3987
|
+
const data = this.safeValue (response, 'result');
|
3988
|
+
const rates = [];
|
3989
|
+
for (let i = 0; i < data.length; i++) {
|
3990
|
+
const entry = data[i];
|
3991
|
+
rates.push ({
|
3992
|
+
'currency': this.safeCurrencyCode (this.safeString (entry, 'coinName')),
|
3993
|
+
'rate': this.safeNumber (entry, 'interestRateOfDay'),
|
3994
|
+
'period': this.safeNumber (entry, 'repaymentDay'),
|
3995
|
+
'timestamp': timestamp,
|
3996
|
+
'datetime': this.iso8601 (timestamp),
|
3997
|
+
'info': entry,
|
3998
|
+
});
|
3999
|
+
}
|
4000
|
+
return rates;
|
4001
|
+
}
|
4002
|
+
|
4003
|
+
nonce () {
|
4004
|
+
return this.milliseconds ();
|
4005
|
+
}
|
4006
|
+
|
4007
|
+
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
4008
|
+
const [ section, version, access ] = api;
|
4009
|
+
let url = this.implodeHostname (this.urls['api'][section][version][access]);
|
4010
|
+
if (access === 'public') {
|
4011
|
+
if (path === 'getFeeInfo') {
|
4012
|
+
url = this.implodeHostname (this.urls['api'][section][version]['private']) + '/' + path;
|
4013
|
+
} else {
|
4014
|
+
url += '/' + version + '/' + path;
|
4015
|
+
}
|
4016
|
+
if (Object.keys (params).length) {
|
4017
|
+
url += '?' + this.urlencode (params);
|
4018
|
+
}
|
4019
|
+
} else if (section === 'contract') {
|
4020
|
+
const timestamp = this.milliseconds ();
|
4021
|
+
const iso8601 = this.iso8601 (timestamp);
|
4022
|
+
let signedString = iso8601 + method + '/Server/api/' + version + '/' + path;
|
4023
|
+
params = this.keysort (params);
|
4024
|
+
headers = {
|
4025
|
+
'ZB-APIKEY': this.apiKey,
|
4026
|
+
'ZB-TIMESTAMP': iso8601,
|
4027
|
+
// 'ZB-LAN': 'cn', // cn, en, kr
|
4028
|
+
};
|
4029
|
+
url += '/' + version + '/' + path;
|
4030
|
+
if (method === 'POST') {
|
4031
|
+
headers['Content-Type'] = 'application/json';
|
4032
|
+
body = this.json (params);
|
4033
|
+
signedString += this.urlencode (params);
|
4034
|
+
} else {
|
4035
|
+
if (Object.keys (params).length) {
|
4036
|
+
const query = this.urlencode (params);
|
4037
|
+
url += '?' + query;
|
4038
|
+
signedString += query;
|
4039
|
+
}
|
4040
|
+
}
|
4041
|
+
const secret = this.hash (this.encode (this.secret), 'sha1');
|
4042
|
+
const signature = this.hmac (this.encode (signedString), this.encode (secret), 'sha256', 'base64');
|
4043
|
+
headers['ZB-SIGN'] = signature;
|
4044
|
+
} else {
|
4045
|
+
let query = this.keysort (this.extend ({
|
4046
|
+
'method': path,
|
4047
|
+
'accesskey': this.apiKey,
|
4048
|
+
}, params));
|
4049
|
+
const nonce = this.nonce ();
|
4050
|
+
query = this.keysort (query);
|
4051
|
+
const auth = this.rawencode (query);
|
4052
|
+
const secret = this.hash (this.encode (this.secret), 'sha1');
|
4053
|
+
const signature = this.hmac (this.encode (auth), this.encode (secret), 'md5');
|
4054
|
+
const suffix = 'sign=' + signature + '&reqTime=' + nonce.toString ();
|
4055
|
+
url += '/' + path + '?' + auth + '&' + suffix;
|
4056
|
+
}
|
4057
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
4058
|
+
}
|
4059
|
+
|
4060
|
+
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
4061
|
+
if (response === undefined) {
|
4062
|
+
return; // fallback to default error handler
|
4063
|
+
}
|
4064
|
+
if (body[0] === '{') {
|
4065
|
+
const feedback = this.id + ' ' + body;
|
4066
|
+
this.throwBroadlyMatchedException (this.exceptions['broad'], body, feedback);
|
4067
|
+
if ('code' in response) {
|
4068
|
+
const code = this.safeString (response, 'code');
|
4069
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], code, feedback);
|
4070
|
+
if ((code !== '1000') && (code !== '10000')) {
|
4071
|
+
throw new ExchangeError (feedback);
|
4072
|
+
}
|
4073
|
+
}
|
4074
|
+
// special case for {"result":false,"message":"服务端忙碌"} (a "Busy Server" reply)
|
4075
|
+
const result = this.safeValue (response, 'result');
|
4076
|
+
if (result !== undefined) {
|
4077
|
+
if (!result) {
|
4078
|
+
const message = this.safeString (response, 'message');
|
4079
|
+
if (message === '服务端忙碌') {
|
4080
|
+
throw new ExchangeNotAvailable (feedback);
|
4081
|
+
} else {
|
4082
|
+
throw new ExchangeError (feedback);
|
4083
|
+
}
|
4084
|
+
}
|
4085
|
+
}
|
4086
|
+
}
|
4087
|
+
}
|
4088
|
+
};
|