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
@@ -0,0 +1,1748 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const { BadSymbol, ExchangeError, ArgumentsRequired, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, InvalidOrder, DDoSProtection, InvalidNonce, AuthenticationError, BadRequest } = require ('./base/errors');
|
7
|
+
const { TICK_SIZE } = require ('./base/functions/number');
|
8
|
+
const Precise = require ('./base/Precise');
|
9
|
+
|
10
|
+
// ---------------------------------------------------------------------------
|
11
|
+
|
12
|
+
module.exports = class currencycom extends Exchange {
|
13
|
+
describe () {
|
14
|
+
return this.deepExtend (super.describe (), {
|
15
|
+
'id': 'currencycom',
|
16
|
+
'name': 'Currency.com',
|
17
|
+
'countries': [ 'BY' ], // Belarus
|
18
|
+
'rateLimit': 100,
|
19
|
+
'certified': true,
|
20
|
+
'pro': true,
|
21
|
+
'version': 'v2',
|
22
|
+
// new metainfo interface
|
23
|
+
'has': {
|
24
|
+
'CORS': undefined,
|
25
|
+
'spot': true,
|
26
|
+
'margin': true,
|
27
|
+
'swap': true,
|
28
|
+
'future': false,
|
29
|
+
'option': false,
|
30
|
+
'addMargin': undefined,
|
31
|
+
'cancelAllOrders': undefined,
|
32
|
+
'cancelOrder': true,
|
33
|
+
'cancelOrders': undefined,
|
34
|
+
'createDepositAddress': undefined,
|
35
|
+
'createLimitOrder': true,
|
36
|
+
'createMarketOrder': true,
|
37
|
+
'createOrder': true,
|
38
|
+
'createStopLimitOrder': true,
|
39
|
+
'createStopMarketOrder': true,
|
40
|
+
'createStopOrder': true,
|
41
|
+
'editOrder': 'emulated',
|
42
|
+
'fetchAccounts': true,
|
43
|
+
'fetchBalance': true,
|
44
|
+
'fetchBidsAsks': undefined,
|
45
|
+
'fetchBorrowRate': undefined,
|
46
|
+
'fetchBorrowRateHistory': undefined,
|
47
|
+
'fetchBorrowRates': undefined,
|
48
|
+
'fetchBorrowRatesPerSymbol': undefined,
|
49
|
+
'fetchCanceledOrders': undefined,
|
50
|
+
'fetchClosedOrder': undefined,
|
51
|
+
'fetchClosedOrders': undefined,
|
52
|
+
'fetchCurrencies': true,
|
53
|
+
'fetchDeposit': undefined,
|
54
|
+
'fetchDepositAddress': true,
|
55
|
+
'fetchDepositAddresses': false,
|
56
|
+
'fetchDepositAddressesByNetwork': false,
|
57
|
+
'fetchDeposits': true,
|
58
|
+
'fetchFundingFee': undefined,
|
59
|
+
'fetchFundingFees': undefined,
|
60
|
+
'fetchFundingHistory': false,
|
61
|
+
'fetchFundingRate': false,
|
62
|
+
'fetchFundingRateHistory': false,
|
63
|
+
'fetchFundingRates': false,
|
64
|
+
'fetchIndexOHLCV': false,
|
65
|
+
'fetchL2OrderBook': true,
|
66
|
+
'fetchLedger': true,
|
67
|
+
'fetchLedgerEntry': false,
|
68
|
+
'fetchLeverage': true,
|
69
|
+
'fetchLeverageTiers': false,
|
70
|
+
'fetchMarkets': true,
|
71
|
+
'fetchMarkOHLCV': false,
|
72
|
+
'fetchMyTrades': true,
|
73
|
+
'fetchOHLCV': true,
|
74
|
+
'fetchOpenOrder': undefined,
|
75
|
+
'fetchOpenOrders': true,
|
76
|
+
'fetchOrder': undefined,
|
77
|
+
'fetchOrderBook': true,
|
78
|
+
'fetchOrderBooks': undefined,
|
79
|
+
'fetchOrders': undefined,
|
80
|
+
'fetchOrderTrades': undefined,
|
81
|
+
'fetchPosition': undefined,
|
82
|
+
'fetchPositions': true,
|
83
|
+
'fetchPositionsRisk': undefined,
|
84
|
+
'fetchPremiumIndexOHLCV': false,
|
85
|
+
'fetchTicker': true,
|
86
|
+
'fetchTickers': true,
|
87
|
+
'fetchTime': true,
|
88
|
+
'fetchTrades': true,
|
89
|
+
'fetchTradingFee': false,
|
90
|
+
'fetchTradingFees': true,
|
91
|
+
'fetchTradingLimits': undefined,
|
92
|
+
'fetchTransactions': true,
|
93
|
+
'fetchTransfers': undefined,
|
94
|
+
'fetchWithdrawal': undefined,
|
95
|
+
'fetchWithdrawals': true,
|
96
|
+
'reduceMargin': undefined,
|
97
|
+
'setLeverage': undefined,
|
98
|
+
'setMarginMode': undefined,
|
99
|
+
'setPositionMode': undefined,
|
100
|
+
'signIn': undefined,
|
101
|
+
'transfer': undefined,
|
102
|
+
'withdraw': undefined,
|
103
|
+
},
|
104
|
+
'timeframes': {
|
105
|
+
'1m': '1m',
|
106
|
+
'5m': '5m',
|
107
|
+
'10m': '10m',
|
108
|
+
'15m': '15m',
|
109
|
+
'30m': '30m',
|
110
|
+
'1h': '1h',
|
111
|
+
'4h': '4h',
|
112
|
+
'1d': '1d',
|
113
|
+
'1w': '1w',
|
114
|
+
},
|
115
|
+
'hostname': 'backend.currency.com',
|
116
|
+
'urls': {
|
117
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/83718672-36745c00-a63e-11ea-81a9-677b1f789a4d.jpg',
|
118
|
+
'api': {
|
119
|
+
'public': 'https://api-adapter.{hostname}/api',
|
120
|
+
'private': 'https://api-adapter.{hostname}/api',
|
121
|
+
'marketcap': 'https://marketcap.{hostname}/api',
|
122
|
+
},
|
123
|
+
'test': {
|
124
|
+
'public': 'https://demo-api-adapter.{hostname}/api',
|
125
|
+
'private': 'https://demo-api-adapter.{hostname}/api',
|
126
|
+
},
|
127
|
+
'www': 'https://www.currency.com',
|
128
|
+
'referral': 'https://currency.com/trading/signup?c=362jaimv&pid=referral',
|
129
|
+
'doc': [
|
130
|
+
'https://currency.com/api',
|
131
|
+
],
|
132
|
+
'fees': 'https://currency.com/fees-charges',
|
133
|
+
},
|
134
|
+
// rate-limits are described at: https://currency.com/api-get-started
|
135
|
+
'api': {
|
136
|
+
'public': {
|
137
|
+
'get': {
|
138
|
+
'v1/time': 1,
|
139
|
+
'v1/exchangeInfo': 1,
|
140
|
+
'v1/depth': 1,
|
141
|
+
'v1/aggTrades': 1,
|
142
|
+
'v1/klines': 1,
|
143
|
+
'v1/ticker/24hr': 1,
|
144
|
+
'v2/time': 1,
|
145
|
+
'v2/exchangeInfo': 1,
|
146
|
+
'v2/depth': 1,
|
147
|
+
'v2/aggTrades': 1,
|
148
|
+
'v2/klines': 1,
|
149
|
+
'v2/ticker/24hr': 1,
|
150
|
+
},
|
151
|
+
},
|
152
|
+
'marketcap': {
|
153
|
+
'get': {
|
154
|
+
'v1/assets': 1,
|
155
|
+
'v1/candles': 1,
|
156
|
+
'v1/orderbook': 1,
|
157
|
+
'v1/summary': 1,
|
158
|
+
'v1/ticker': 1,
|
159
|
+
'v1/token/assets': 1,
|
160
|
+
'v1/token/orderbook': 1,
|
161
|
+
'v1/token/summary': 1,
|
162
|
+
'v1/token/ticker': 1,
|
163
|
+
'v1/token/trades': 1,
|
164
|
+
'v1/token_crypto/OHLC': 1,
|
165
|
+
'v1/token_crypto/assets': 1,
|
166
|
+
'v1/token_crypto/orderbook': 1,
|
167
|
+
'v1/token_crypto/summary': 1,
|
168
|
+
'v1/token_crypto/ticker': 1,
|
169
|
+
'v1/token_crypto/trades': 1,
|
170
|
+
'v1/trades': 1,
|
171
|
+
},
|
172
|
+
},
|
173
|
+
'private': {
|
174
|
+
'get': {
|
175
|
+
'v1/account': 1,
|
176
|
+
'v1/currencies': 1,
|
177
|
+
'v1/deposits': 1,
|
178
|
+
'v1/depositAddress': 1,
|
179
|
+
'v1/ledger': 1,
|
180
|
+
'v1/leverageSettings': 1,
|
181
|
+
'v1/myTrades': 1,
|
182
|
+
'v1/openOrders': 1,
|
183
|
+
'v1/tradingPositions': 1,
|
184
|
+
'v1/tradingPositionsHistory': 1,
|
185
|
+
'v1/transactions': 1,
|
186
|
+
'v1/withdrawals': 1,
|
187
|
+
'v2/account': 1,
|
188
|
+
'v2/currencies': 1,
|
189
|
+
'v2/deposits': 1,
|
190
|
+
'v2/depositAddress': 1,
|
191
|
+
'v2/ledger': 1,
|
192
|
+
'v2/leverageSettings': 1,
|
193
|
+
'v2/myTrades': 1,
|
194
|
+
'v2/openOrders': 1,
|
195
|
+
'v2/tradingPositions': 1,
|
196
|
+
'v2/tradingPositionsHistory': 1,
|
197
|
+
'v2/transactions': 1,
|
198
|
+
'v2/withdrawals': 1,
|
199
|
+
},
|
200
|
+
'post': {
|
201
|
+
'v1/order': 1,
|
202
|
+
'v1/updateTradingPosition': 1,
|
203
|
+
'v1/updateTradingOrder': 1,
|
204
|
+
'v1/closeTradingPosition': 1,
|
205
|
+
'v2/order': 1,
|
206
|
+
'v2/updateTradingPosition': 1,
|
207
|
+
'v2/updateTradingOrder': 1,
|
208
|
+
'v2/closeTradingPosition': 1,
|
209
|
+
},
|
210
|
+
'delete': {
|
211
|
+
'v1/order': 1,
|
212
|
+
'v2/order': 1,
|
213
|
+
},
|
214
|
+
},
|
215
|
+
},
|
216
|
+
'fees': {
|
217
|
+
'trading': {
|
218
|
+
'feeSide': 'get',
|
219
|
+
'tierBased': false,
|
220
|
+
'percentage': true,
|
221
|
+
'taker': this.parseNumber ('0.002'),
|
222
|
+
'maker': this.parseNumber ('0.002'),
|
223
|
+
},
|
224
|
+
},
|
225
|
+
'precisionMode': TICK_SIZE,
|
226
|
+
// exchange-specific options
|
227
|
+
'options': {
|
228
|
+
'defaultTimeInForce': 'GTC', // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel, 'FOK' = Fill Or Kill
|
229
|
+
'warnOnFetchOpenOrdersWithoutSymbol': true,
|
230
|
+
'recvWindow': 5 * 1000, // 5 sec, default
|
231
|
+
'timeDifference': 0, // the difference between system clock and Binance clock
|
232
|
+
'adjustForTimeDifference': false, // controls the adjustment logic upon instantiation
|
233
|
+
'parseOrderToPrecision': false, // force amounts and costs in parseOrder to precision
|
234
|
+
'newOrderRespType': {
|
235
|
+
'market': 'FULL', // 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
236
|
+
'limit': 'RESULT', // we change it from 'ACK' by default to 'RESULT'
|
237
|
+
'stop': 'RESULT',
|
238
|
+
},
|
239
|
+
'leverage_markets_suffix': '_LEVERAGE',
|
240
|
+
'collateralCurrencies': [ 'USD', 'EUR', 'USDT' ],
|
241
|
+
},
|
242
|
+
'exceptions': {
|
243
|
+
'broad': {
|
244
|
+
'FIELD_VALIDATION_ERROR Cancel is available only for LIMIT order': InvalidOrder,
|
245
|
+
'API key does not exist': AuthenticationError,
|
246
|
+
'Order would trigger immediately.': InvalidOrder,
|
247
|
+
'Account has insufficient balance for requested action.': InsufficientFunds,
|
248
|
+
'Rest API trading is not enabled.': ExchangeNotAvailable,
|
249
|
+
'Combination of parameters invalid': BadRequest,
|
250
|
+
'Invalid limit price': BadRequest,
|
251
|
+
'Only leverage symbol allowed here:': BadSymbol, // when you fetchLeverage for non-leverage symbols, like 'BTC/USDT' instead of 'BTC/USDT_LEVERAGE': {"code":"-1128","msg":"Only leverage symbol allowed here: BTC/USDT"}
|
252
|
+
},
|
253
|
+
'exact': {
|
254
|
+
'-1000': ExchangeNotAvailable, // {"code":-1000,"msg":"An unknown error occured while processing the request."}
|
255
|
+
'-1013': InvalidOrder, // createOrder -> 'invalid quantity'/'invalid price'/MIN_NOTIONAL
|
256
|
+
'-1021': InvalidNonce, // 'your time is ahead of server'
|
257
|
+
'-1022': AuthenticationError, // {"code":-1022,"msg":"Signature for this request is not valid."}
|
258
|
+
'-1100': InvalidOrder, // createOrder(symbol, 1, asdf) -> 'Illegal characters found in parameter 'price'
|
259
|
+
'-1104': ExchangeError, // Not all sent parameters were read, read 8 parameters but was sent 9
|
260
|
+
'-1025': AuthenticationError, // {"code":-1025,"msg":"Invalid API-key, IP, or permissions for action"}
|
261
|
+
'-1128': BadRequest, // {"code":-1128,"msg":"Combination of optional parameters invalid."} | {"code":"-1128","msg":"Combination of parameters invalid"} | {"code":"-1128","msg":"Invalid limit price"}
|
262
|
+
'-2010': ExchangeError, // generic error code for createOrder -> 'Account has insufficient balance for requested action.', {"code":-2010,"msg":"Rest API trading is not enabled."}, etc...
|
263
|
+
'-2011': OrderNotFound, // cancelOrder(1, 'BTC/USDT') -> 'UNKNOWN_ORDER'
|
264
|
+
'-2013': OrderNotFound, // fetchOrder (1, 'BTC/USDT') -> 'Order does not exist'
|
265
|
+
'-2014': AuthenticationError, // { "code":-2014, "msg": "API-key format invalid." }
|
266
|
+
'-2015': AuthenticationError, // "Invalid API-key, IP, or permissions for action."
|
267
|
+
},
|
268
|
+
},
|
269
|
+
'commonCurrencies': {
|
270
|
+
'ACN': 'Accenture',
|
271
|
+
'AMC': 'AMC Entertainment Holdings',
|
272
|
+
'BNS': 'Bank of Nova Scotia',
|
273
|
+
'CAR': 'Avis Budget Group Inc',
|
274
|
+
'CLR': 'Continental Resources',
|
275
|
+
'EDU': 'New Oriental Education & Technology Group Inc',
|
276
|
+
'ETN': 'Eaton',
|
277
|
+
'FOX': 'Fox Corporation',
|
278
|
+
'GM': 'General Motors Co',
|
279
|
+
'IQ': 'iQIYI',
|
280
|
+
'OSK': 'Oshkosh',
|
281
|
+
'PLAY': "Dave & Buster's Entertainment",
|
282
|
+
},
|
283
|
+
});
|
284
|
+
}
|
285
|
+
|
286
|
+
nonce () {
|
287
|
+
return this.milliseconds () - this.options['timeDifference'];
|
288
|
+
}
|
289
|
+
|
290
|
+
async fetchTime (params = {}) {
|
291
|
+
const response = await this.publicGetV2Time (params);
|
292
|
+
//
|
293
|
+
// {
|
294
|
+
// "serverTime": 1590998366609
|
295
|
+
// }
|
296
|
+
//
|
297
|
+
return this.safeInteger (response, 'serverTime');
|
298
|
+
}
|
299
|
+
|
300
|
+
async fetchCurrencies (params = {}) {
|
301
|
+
// requires authentication
|
302
|
+
if (!this.checkRequiredCredentials (false)) {
|
303
|
+
return undefined;
|
304
|
+
}
|
305
|
+
const response = await this.privateGetV2Currencies (params);
|
306
|
+
//
|
307
|
+
// [
|
308
|
+
// {
|
309
|
+
// "name": "Euro",
|
310
|
+
// "displaySymbol": "EUR.cx",
|
311
|
+
// "precision": "2",
|
312
|
+
// "type": "FIAT",
|
313
|
+
// "minWithdrawal": "90.0",
|
314
|
+
// "maxWithdrawal": "1.0E+8",
|
315
|
+
// "commissionMin": "0.02", // some instruments do not have this property
|
316
|
+
// "commissionPercent": "1.5", // some instruments do not have this property
|
317
|
+
// "minDeposit": "90.0",
|
318
|
+
// },
|
319
|
+
// {
|
320
|
+
// name: "Bitcoin",
|
321
|
+
// displaySymbol: "BTC",
|
322
|
+
// precision: "8",
|
323
|
+
// type: "CRYPTO", // only a few major currencies have this value, others like USDT have a value of "TOKEN"
|
324
|
+
// minWithdrawal: "0.00020",
|
325
|
+
// commissionFixed: "0.00010",
|
326
|
+
// minDeposit: "0.00010",
|
327
|
+
// },
|
328
|
+
// ]
|
329
|
+
//
|
330
|
+
const result = {};
|
331
|
+
for (let i = 0; i < response.length; i++) {
|
332
|
+
const currency = response[i];
|
333
|
+
const id = this.safeString (currency, 'displaySymbol');
|
334
|
+
const code = this.safeCurrencyCode (id);
|
335
|
+
const fee = this.safeNumber (currency, 'commissionFixed');
|
336
|
+
const precision = this.safeInteger (currency, 'precision');
|
337
|
+
result[code] = {
|
338
|
+
'id': id,
|
339
|
+
'code': code,
|
340
|
+
'address': this.safeString (currency, 'baseAddress'),
|
341
|
+
'type': this.safeStringLower (currency, 'type'),
|
342
|
+
'name': this.safeString (currency, 'name'),
|
343
|
+
'active': undefined,
|
344
|
+
'deposit': undefined,
|
345
|
+
'withdraw': undefined,
|
346
|
+
'fee': fee,
|
347
|
+
'precision': precision,
|
348
|
+
'limits': {
|
349
|
+
'amount': {
|
350
|
+
'min': undefined,
|
351
|
+
'max': undefined,
|
352
|
+
},
|
353
|
+
'withdraw': {
|
354
|
+
'min': this.safeNumber (currency, 'minWithdrawal'),
|
355
|
+
'max': this.safeNumber (currency, 'maxWithdrawal'),
|
356
|
+
},
|
357
|
+
'deposit': {
|
358
|
+
'min': this.safeNumber (currency, 'minDeposit'),
|
359
|
+
'max': undefined,
|
360
|
+
},
|
361
|
+
},
|
362
|
+
'info': currency,
|
363
|
+
};
|
364
|
+
}
|
365
|
+
return result;
|
366
|
+
}
|
367
|
+
|
368
|
+
async fetchMarkets (params = {}) {
|
369
|
+
const response = await this.publicGetV2ExchangeInfo (params);
|
370
|
+
//
|
371
|
+
// {
|
372
|
+
// timezone: "UTC",
|
373
|
+
// serverTime: "1645186287261",
|
374
|
+
// rateLimits: [
|
375
|
+
// { rateLimitType: "REQUEST_WEIGHT", interval: "MINUTE", intervalNum: "1", limit: "1200" },
|
376
|
+
// { rateLimitType: "ORDERS", interval: "SECOND", intervalNum: "1", limit: "10" },
|
377
|
+
// { rateLimitType: "ORDERS", interval: "DAY", intervalNum: "1", limit: "864000" },
|
378
|
+
// ],
|
379
|
+
// exchangeFilters: [],
|
380
|
+
// symbols: [
|
381
|
+
// {
|
382
|
+
// symbol: "BTC/USDT", // BTC/USDT, BTC/USDT_LEVERAGE
|
383
|
+
// name: "Bitcoin / Tether",
|
384
|
+
// status: "TRADING", // TRADING, BREAK, HALT
|
385
|
+
// baseAsset: "BTC",
|
386
|
+
// baseAssetPrecision: "4",
|
387
|
+
// quoteAsset: "USDT",
|
388
|
+
// quoteAssetId: "USDT", // USDT, USDT_LEVERAGE
|
389
|
+
// quotePrecision: "4",
|
390
|
+
// orderTypes: [ "LIMIT", "MARKET" ], // LIMIT, MARKET, STOP
|
391
|
+
// filters: [
|
392
|
+
// { filterType: "LOT_SIZE", minQty: "0.0001", maxQty: "100", stepSize: "0.0001", },
|
393
|
+
// { filterType: "MIN_NOTIONAL", minNotional: "5", },
|
394
|
+
// ],
|
395
|
+
// marketModes: [ "REGULAR" ], // CLOSE_ONLY, LONG_ONLY, REGULAR
|
396
|
+
// marketType: "SPOT", // SPOT, LEVERAGE
|
397
|
+
// longRate: -0.0684932, // LEVERAGE only
|
398
|
+
// shortRate: -0.0684932, // LEVERAGE only
|
399
|
+
// swapChargeInterval: 1440, // LEVERAGE only
|
400
|
+
// country: "",
|
401
|
+
// sector: "",
|
402
|
+
// industry: "",
|
403
|
+
// tradingHours: "UTC; Mon - 22:00, 22:05 -; Tue - 22:00, 22:05 -; Wed - 22:00, 22:05 -; Thu - 22:00, 22:05 -; Fri - 22:00, 23:01 -; Sat - 22:00, 22:05 -; Sun - 21:00, 22:05 -",
|
404
|
+
// tickSize: "0.01",
|
405
|
+
// tickValue: "403.4405", // not available in BTC/USDT_LEVERAGE, but available in BTC/USD_LEVERAGE
|
406
|
+
// exchangeFee: "0.2", // SPOT only
|
407
|
+
// tradingFee: 0.075, // LEVERAGE only
|
408
|
+
// makerFee: -0.025, // LEVERAGE only
|
409
|
+
// takerFee: 0.06, // LEVERAGE only
|
410
|
+
// maxSLGap: 50, // LEVERAGE only
|
411
|
+
// minSLGap: 1, // LEVERAGE only
|
412
|
+
// maxTPGap: 50, // LEVERAGE only
|
413
|
+
// minTPGap: 0.5, // LEVERAGE only
|
414
|
+
// assetType: "CRYPTOCURRENCY",
|
415
|
+
// },
|
416
|
+
// ]
|
417
|
+
// }
|
418
|
+
//
|
419
|
+
if (this.options['adjustForTimeDifference']) {
|
420
|
+
await this.loadTimeDifference ();
|
421
|
+
}
|
422
|
+
const markets = this.safeValue (response, 'symbols');
|
423
|
+
const result = [];
|
424
|
+
for (let i = 0; i < markets.length; i++) {
|
425
|
+
const market = markets[i];
|
426
|
+
const id = this.safeString (market, 'symbol');
|
427
|
+
const baseId = this.safeString (market, 'baseAsset');
|
428
|
+
const quoteId = this.safeString (market, 'quoteAsset');
|
429
|
+
const base = this.safeCurrencyCode (baseId);
|
430
|
+
const quote = this.safeCurrencyCode (quoteId);
|
431
|
+
let symbol = base + '/' + quote;
|
432
|
+
const type = this.safeString (market, 'marketType');
|
433
|
+
const spot = (type === 'SPOT');
|
434
|
+
const futures = false;
|
435
|
+
const swap = (type === 'LEVERAGE');
|
436
|
+
const margin = swap; // as we decided to set
|
437
|
+
if (swap) {
|
438
|
+
symbol = symbol.replace (this.options['leverage_markets_suffix'], '');
|
439
|
+
symbol += ':' + quote;
|
440
|
+
}
|
441
|
+
const active = this.safeString (market, 'status') === 'TRADING';
|
442
|
+
// to set taker & maker fees, we use one from the below data - pairs either have 'exchangeFee' or 'tradingFee', if none of them (rare cases), then they should have 'takerFee & makerFee'
|
443
|
+
const exchangeFee = this.safeString2 (market, 'exchangeFee', 'tradingFee');
|
444
|
+
let makerFee = this.safeString (market, 'makerFee', exchangeFee);
|
445
|
+
let takerFee = this.safeString (market, 'takerFee', exchangeFee);
|
446
|
+
makerFee = Precise.stringDiv (makerFee, '100');
|
447
|
+
takerFee = Precise.stringDiv (takerFee, '100');
|
448
|
+
const filters = this.safeValue (market, 'filters', []);
|
449
|
+
const filtersByType = this.indexBy (filters, 'filterType');
|
450
|
+
let limitPriceMin = undefined;
|
451
|
+
let limitPriceMax = undefined;
|
452
|
+
let precisionPrice = this.safeNumber (market, 'tickSize');
|
453
|
+
if ('PRICE_FILTER' in filtersByType) {
|
454
|
+
const filter = this.safeValue (filtersByType, 'PRICE_FILTER', {});
|
455
|
+
precisionPrice = this.safeNumber (filter, 'tickSize');
|
456
|
+
// PRICE_FILTER reports zero values for maxPrice
|
457
|
+
// since they updated filter types in November 2018
|
458
|
+
// https://github.com/ccxt/ccxt/issues/4286
|
459
|
+
// therefore limits['price']['max'] doesn't have any meaningful value except undefined
|
460
|
+
limitPriceMin = this.safeNumber (filter, 'minPrice');
|
461
|
+
const maxPrice = this.safeNumber (filter, 'maxPrice');
|
462
|
+
if ((maxPrice !== undefined) && (maxPrice > 0)) {
|
463
|
+
limitPriceMax = maxPrice;
|
464
|
+
}
|
465
|
+
}
|
466
|
+
let precisionAmount = this.parseNumber (this.parsePrecision (this.safeString (market, 'baseAssetPrecision')));
|
467
|
+
let limitAmount = {
|
468
|
+
'min': undefined,
|
469
|
+
'max': undefined,
|
470
|
+
};
|
471
|
+
if ('LOT_SIZE' in filtersByType) {
|
472
|
+
const filter = this.safeValue (filtersByType, 'LOT_SIZE', {});
|
473
|
+
precisionAmount = this.safeNumber (filter, 'stepSize');
|
474
|
+
limitAmount = {
|
475
|
+
'min': this.safeNumber (filter, 'minQty'),
|
476
|
+
'max': this.safeNumber (filter, 'maxQty'),
|
477
|
+
};
|
478
|
+
}
|
479
|
+
let limitMarket = {
|
480
|
+
'min': undefined,
|
481
|
+
'max': undefined,
|
482
|
+
};
|
483
|
+
if ('MARKET_LOT_SIZE' in filtersByType) {
|
484
|
+
const filter = this.safeValue (filtersByType, 'MARKET_LOT_SIZE', {});
|
485
|
+
limitMarket = {
|
486
|
+
'min': this.safeNumber (filter, 'minQty'),
|
487
|
+
'max': this.safeNumber (filter, 'maxQty'),
|
488
|
+
};
|
489
|
+
}
|
490
|
+
let costMin = undefined;
|
491
|
+
if ('MIN_NOTIONAL' in filtersByType) {
|
492
|
+
const filter = this.safeValue (filtersByType, 'MIN_NOTIONAL', {});
|
493
|
+
costMin = this.safeNumber (filter, 'minNotional');
|
494
|
+
}
|
495
|
+
const isContract = swap || futures;
|
496
|
+
result.push ({
|
497
|
+
'id': id,
|
498
|
+
'symbol': symbol,
|
499
|
+
'base': base,
|
500
|
+
'quote': quote,
|
501
|
+
'settle': undefined,
|
502
|
+
'baseId': baseId,
|
503
|
+
'quoteId': quoteId,
|
504
|
+
'settleId': undefined,
|
505
|
+
'type': type,
|
506
|
+
'spot': spot,
|
507
|
+
'margin': margin,
|
508
|
+
'swap': swap,
|
509
|
+
'future': futures,
|
510
|
+
'option': false,
|
511
|
+
'active': active,
|
512
|
+
'contract': isContract,
|
513
|
+
'linear': isContract ? true : undefined,
|
514
|
+
'inverse': undefined,
|
515
|
+
'taker': this.parseNumber (takerFee),
|
516
|
+
'maker': this.parseNumber (makerFee),
|
517
|
+
'contractSize': undefined,
|
518
|
+
'expiry': undefined,
|
519
|
+
'expiryDatetime': undefined,
|
520
|
+
'strike': undefined,
|
521
|
+
'optionType': undefined,
|
522
|
+
'precision': {
|
523
|
+
'amount': precisionAmount,
|
524
|
+
'price': precisionPrice,
|
525
|
+
},
|
526
|
+
'limits': {
|
527
|
+
'leverage': {
|
528
|
+
'min': undefined,
|
529
|
+
'max': undefined,
|
530
|
+
},
|
531
|
+
'amount': limitAmount,
|
532
|
+
'market': limitMarket,
|
533
|
+
'price': {
|
534
|
+
'min': limitPriceMin,
|
535
|
+
'max': limitPriceMax,
|
536
|
+
},
|
537
|
+
'cost': {
|
538
|
+
'min': costMin,
|
539
|
+
'max': undefined,
|
540
|
+
},
|
541
|
+
},
|
542
|
+
'info': market,
|
543
|
+
});
|
544
|
+
}
|
545
|
+
return result;
|
546
|
+
}
|
547
|
+
|
548
|
+
async fetchAccounts (params = {}) {
|
549
|
+
const response = await this.privateGetV2Account (params);
|
550
|
+
//
|
551
|
+
// {
|
552
|
+
// "makerCommission": "0.20",
|
553
|
+
// "takerCommission": "0.20",
|
554
|
+
// "buyerCommission": "0.20",
|
555
|
+
// "sellerCommission": "0.20",
|
556
|
+
// "canTrade": true,
|
557
|
+
// "canWithdraw": true,
|
558
|
+
// "canDeposit": true,
|
559
|
+
// "updateTime": "1645266330",
|
560
|
+
// "userId": "644722",
|
561
|
+
// "balances": [
|
562
|
+
// {
|
563
|
+
// "accountId": "120702016179403605",
|
564
|
+
// "collateralCurrency": false,
|
565
|
+
// "asset": "CAKE",
|
566
|
+
// "free": "3.1",
|
567
|
+
// "locked": "0.0",
|
568
|
+
// "default": false,
|
569
|
+
// },
|
570
|
+
// {
|
571
|
+
// "accountId": "109698017713125316",
|
572
|
+
// "collateralCurrency": true,
|
573
|
+
// "asset": "USD",
|
574
|
+
// "free": "17.58632",
|
575
|
+
// "locked": "0.0",
|
576
|
+
// "default": true,
|
577
|
+
// }
|
578
|
+
// ]
|
579
|
+
// }
|
580
|
+
//
|
581
|
+
const accounts = this.safeValue (response, 'balances', []);
|
582
|
+
const result = [];
|
583
|
+
for (let i = 0; i < accounts.length; i++) {
|
584
|
+
const account = accounts[i];
|
585
|
+
const accountId = this.safeInteger (account, 'accountId');
|
586
|
+
const currencyId = this.safeString (account, 'asset');
|
587
|
+
const currencyCode = this.safeCurrencyCode (currencyId);
|
588
|
+
result.push ({
|
589
|
+
'id': accountId,
|
590
|
+
'type': undefined,
|
591
|
+
'currency': currencyCode,
|
592
|
+
'info': account,
|
593
|
+
});
|
594
|
+
}
|
595
|
+
return result;
|
596
|
+
}
|
597
|
+
|
598
|
+
async fetchTradingFees (params = {}) {
|
599
|
+
await this.loadMarkets ();
|
600
|
+
const response = await this.privateGetV2Account (params);
|
601
|
+
//
|
602
|
+
// {
|
603
|
+
// makerCommission: '0.20',
|
604
|
+
// takerCommission: '0.20',
|
605
|
+
// buyerCommission: '0.20',
|
606
|
+
// sellerCommission: '0.20',
|
607
|
+
// canTrade: true,
|
608
|
+
// canWithdraw: true,
|
609
|
+
// canDeposit: true,
|
610
|
+
// updateTime: '1645738976',
|
611
|
+
// userId: '-1924114235',
|
612
|
+
// balances: []
|
613
|
+
// }
|
614
|
+
//
|
615
|
+
const makerFee = this.safeNumber (response, 'makerCommission');
|
616
|
+
const takerFee = this.safeNumber (response, 'takerCommission');
|
617
|
+
const result = {};
|
618
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
619
|
+
const symbol = this.symbols[i];
|
620
|
+
result[symbol] = {
|
621
|
+
'info': response,
|
622
|
+
'symbol': symbol,
|
623
|
+
'maker': makerFee,
|
624
|
+
'taker': takerFee,
|
625
|
+
'percentage': true,
|
626
|
+
'tierBased': false,
|
627
|
+
};
|
628
|
+
}
|
629
|
+
return result;
|
630
|
+
}
|
631
|
+
|
632
|
+
parseBalance (response, type = undefined) {
|
633
|
+
//
|
634
|
+
// {
|
635
|
+
// "makerCommission":0.20,
|
636
|
+
// "takerCommission":0.20,
|
637
|
+
// "buyerCommission":0.20,
|
638
|
+
// "sellerCommission":0.20,
|
639
|
+
// "canTrade":true,
|
640
|
+
// "canWithdraw":true,
|
641
|
+
// "canDeposit":true,
|
642
|
+
// "updateTime":1591056268,
|
643
|
+
// "balances":[
|
644
|
+
// {
|
645
|
+
// "accountId":5470306579272368,
|
646
|
+
// "collateralCurrency":true,
|
647
|
+
// "asset":"ETH",
|
648
|
+
// "free":0.0,
|
649
|
+
// "locked":0.0,
|
650
|
+
// "default":false,
|
651
|
+
// },
|
652
|
+
// ]
|
653
|
+
// }
|
654
|
+
//
|
655
|
+
const result = { 'info': response };
|
656
|
+
const balances = this.safeValue (response, 'balances', []);
|
657
|
+
for (let i = 0; i < balances.length; i++) {
|
658
|
+
const balance = balances[i];
|
659
|
+
const currencyId = this.safeString (balance, 'asset');
|
660
|
+
const code = this.safeCurrencyCode (currencyId);
|
661
|
+
const account = this.account ();
|
662
|
+
account['free'] = this.safeString (balance, 'free');
|
663
|
+
account['used'] = this.safeString (balance, 'locked');
|
664
|
+
result[code] = account;
|
665
|
+
}
|
666
|
+
return this.safeBalance (result);
|
667
|
+
}
|
668
|
+
|
669
|
+
async fetchBalance (params = {}) {
|
670
|
+
await this.loadMarkets ();
|
671
|
+
const response = await this.privateGetV2Account (params);
|
672
|
+
//
|
673
|
+
// {
|
674
|
+
// "makerCommission": "0.20",
|
675
|
+
// "takerCommission": "0.20",
|
676
|
+
// "buyerCommission": "0.20",
|
677
|
+
// "sellerCommission": "0.20",
|
678
|
+
// "canTrade": true,
|
679
|
+
// "canWithdraw": true,
|
680
|
+
// "canDeposit": true,
|
681
|
+
// "updateTime": "1645266330",
|
682
|
+
// "userId": "644722",
|
683
|
+
// "balances": [
|
684
|
+
// {
|
685
|
+
// "accountId": "120702016179403605",
|
686
|
+
// "collateralCurrency": false,
|
687
|
+
// "asset": "CAKE",
|
688
|
+
// "free": "1.784",
|
689
|
+
// "locked": "0.0",
|
690
|
+
// "default": false,
|
691
|
+
// },
|
692
|
+
// {
|
693
|
+
// "accountId": "109698017413175316",
|
694
|
+
// "collateralCurrency": true,
|
695
|
+
// "asset": "USD",
|
696
|
+
// "free": "7.58632",
|
697
|
+
// "locked": "0.0",
|
698
|
+
// "default": true,
|
699
|
+
// }
|
700
|
+
// ]
|
701
|
+
// }
|
702
|
+
//
|
703
|
+
return this.parseBalance (response);
|
704
|
+
}
|
705
|
+
|
706
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
707
|
+
await this.loadMarkets ();
|
708
|
+
const market = this.market (symbol);
|
709
|
+
const request = {
|
710
|
+
'symbol': market['id'],
|
711
|
+
};
|
712
|
+
if (limit !== undefined) {
|
713
|
+
request['limit'] = limit; // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000, 5000
|
714
|
+
}
|
715
|
+
const response = await this.publicGetV2Depth (this.extend (request, params));
|
716
|
+
//
|
717
|
+
// {
|
718
|
+
// "lastUpdateId":1590999849037,
|
719
|
+
// "asks":[
|
720
|
+
// [0.02495,60.0345],
|
721
|
+
// [0.02496,34.1],
|
722
|
+
// ...
|
723
|
+
// ],
|
724
|
+
// "bids":[
|
725
|
+
// [0.02487,72.4144854],
|
726
|
+
// [0.02486,24.043],
|
727
|
+
// ...
|
728
|
+
// ]
|
729
|
+
// }
|
730
|
+
//
|
731
|
+
const orderbook = this.parseOrderBook (response, symbol);
|
732
|
+
orderbook['nonce'] = this.safeInteger (response, 'lastUpdateId');
|
733
|
+
return orderbook;
|
734
|
+
}
|
735
|
+
|
736
|
+
parseTicker (ticker, market = undefined) {
|
737
|
+
//
|
738
|
+
// fetchTicker
|
739
|
+
//
|
740
|
+
// {
|
741
|
+
// "symbol":"ETH/BTC",
|
742
|
+
// "priceChange":"0.00030",
|
743
|
+
// "priceChangePercent":"1.21",
|
744
|
+
// "weightedAvgPrice":"0.02481",
|
745
|
+
// "prevClosePrice":"0.02447",
|
746
|
+
// "lastPrice":"0.02477",
|
747
|
+
// "lastQty":"60.0",
|
748
|
+
// "bidPrice":"0.02477",
|
749
|
+
// "askPrice":"0.02484",
|
750
|
+
// "openPrice":"0.02447",
|
751
|
+
// "highPrice":"0.02524",
|
752
|
+
// "lowPrice":"0.02438",
|
753
|
+
// "volume":"11.97",
|
754
|
+
// "quoteVolume":"0.298053",
|
755
|
+
// "openTime":1590969600000,
|
756
|
+
// "closeTime":1591000072693
|
757
|
+
// }
|
758
|
+
//
|
759
|
+
// fetchTickers
|
760
|
+
//
|
761
|
+
// {
|
762
|
+
// "symbol": "SHIB/USD_LEVERAGE",
|
763
|
+
// "weightedAvgPrice": "0.000027595",
|
764
|
+
// "lastPrice": "0.00002737",
|
765
|
+
// "lastQty": "1.11111111E8",
|
766
|
+
// "bidPrice": "0.00002737",
|
767
|
+
// "askPrice": "0.00002782",
|
768
|
+
// "highPrice": "0.00002896",
|
769
|
+
// "lowPrice": "0.00002738",
|
770
|
+
// "volume": "16472160000",
|
771
|
+
// "quoteVolume": "454796.3376",
|
772
|
+
// "openTime": "1645187472000",
|
773
|
+
// "closeTime": "1645273872000",
|
774
|
+
// }
|
775
|
+
//
|
776
|
+
// ws:marketData.subscribe
|
777
|
+
//
|
778
|
+
// {
|
779
|
+
// "symbolName":"TXN",
|
780
|
+
// "bid":139.85,
|
781
|
+
// "bidQty":2500,
|
782
|
+
// "ofr":139.92000000000002,
|
783
|
+
// "ofrQty":2500,
|
784
|
+
// "timestamp":1597850971558
|
785
|
+
// }
|
786
|
+
//
|
787
|
+
const timestamp = this.safeInteger2 (ticker, 'closeTime', 'timestamp');
|
788
|
+
const marketId = this.safeString2 (ticker, 'symbol', 'symbolName');
|
789
|
+
market = this.safeMarket (marketId, market, '/');
|
790
|
+
const last = this.safeString (ticker, 'lastPrice');
|
791
|
+
return this.safeTicker ({
|
792
|
+
'symbol': market['symbol'],
|
793
|
+
'timestamp': timestamp,
|
794
|
+
'datetime': this.iso8601 (timestamp),
|
795
|
+
'high': this.safeString (ticker, 'highPrice'),
|
796
|
+
'low': this.safeString (ticker, 'lowPrice'),
|
797
|
+
'bid': this.safeString2 (ticker, 'bidPrice', 'bid'),
|
798
|
+
'bidVolume': this.safeString (ticker, 'bidQty'),
|
799
|
+
'ask': this.safeString2 (ticker, 'askPrice', 'ofr'),
|
800
|
+
'askVolume': this.safeString (ticker, 'ofrQty'),
|
801
|
+
'vwap': this.safeString (ticker, 'weightedAvgPrice'),
|
802
|
+
'open': this.safeString (ticker, 'openPrice'),
|
803
|
+
'close': last,
|
804
|
+
'last': last,
|
805
|
+
'previousClose': this.safeString (ticker, 'prevClosePrice'), // previous day close
|
806
|
+
'change': this.safeString (ticker, 'priceChange'),
|
807
|
+
'percentage': this.safeString (ticker, 'priceChangePercent'),
|
808
|
+
'average': undefined,
|
809
|
+
'baseVolume': this.safeString (ticker, 'volume'),
|
810
|
+
'quoteVolume': this.safeString (ticker, 'quoteVolume'),
|
811
|
+
'info': ticker,
|
812
|
+
}, market, false);
|
813
|
+
}
|
814
|
+
|
815
|
+
async fetchTicker (symbol, params = {}) {
|
816
|
+
await this.loadMarkets ();
|
817
|
+
const market = this.market (symbol);
|
818
|
+
const request = {
|
819
|
+
'symbol': market['id'],
|
820
|
+
};
|
821
|
+
const response = await this.publicGetV2Ticker24hr (this.extend (request, params));
|
822
|
+
//
|
823
|
+
// {
|
824
|
+
// "symbol":"ETH/BTC",
|
825
|
+
// "priceChange":"0.00030",
|
826
|
+
// "priceChangePercent":"1.21",
|
827
|
+
// "weightedAvgPrice":"0.02481",
|
828
|
+
// "prevClosePrice":"0.02447",
|
829
|
+
// "lastPrice":"0.02477",
|
830
|
+
// "lastQty":"60.0",
|
831
|
+
// "bidPrice":"0.02477",
|
832
|
+
// "askPrice":"0.02484",
|
833
|
+
// "openPrice":"0.02447",
|
834
|
+
// "highPrice":"0.02524",
|
835
|
+
// "lowPrice":"0.02438",
|
836
|
+
// "volume":"11.97",
|
837
|
+
// "quoteVolume":"0.298053",
|
838
|
+
// "openTime":1590969600000,
|
839
|
+
// "closeTime":1591000072693
|
840
|
+
// }
|
841
|
+
//
|
842
|
+
return this.parseTicker (response, market);
|
843
|
+
}
|
844
|
+
|
845
|
+
async fetchTickers (symbols = undefined, params = {}) {
|
846
|
+
await this.loadMarkets ();
|
847
|
+
const response = await this.publicGetV2Ticker24hr (params);
|
848
|
+
//
|
849
|
+
// [
|
850
|
+
// {
|
851
|
+
// "symbol": "SHIB/USD_LEVERAGE",
|
852
|
+
// "weightedAvgPrice": "0.000027595",
|
853
|
+
// "lastPrice": "0.00002737",
|
854
|
+
// "lastQty": "1.11111111E8",
|
855
|
+
// "bidPrice": "0.00002737",
|
856
|
+
// "askPrice": "0.00002782",
|
857
|
+
// "highPrice": "0.00002896",
|
858
|
+
// "lowPrice": "0.00002738",
|
859
|
+
// "volume": "16472160000",
|
860
|
+
// "quoteVolume": "454796.3376",
|
861
|
+
// "openTime": "1645187472000",
|
862
|
+
// "closeTime": "1645273872000",
|
863
|
+
// }
|
864
|
+
// ]
|
865
|
+
//
|
866
|
+
return this.parseTickers (response, symbols);
|
867
|
+
}
|
868
|
+
|
869
|
+
parseOHLCV (ohlcv, market = undefined) {
|
870
|
+
//
|
871
|
+
// [
|
872
|
+
// 1590971040000,
|
873
|
+
// "0.02454",
|
874
|
+
// "0.02456",
|
875
|
+
// "0.02452",
|
876
|
+
// "0.02456",
|
877
|
+
// 249
|
878
|
+
// ]
|
879
|
+
//
|
880
|
+
return [
|
881
|
+
this.safeInteger (ohlcv, 0),
|
882
|
+
this.safeNumber (ohlcv, 1),
|
883
|
+
this.safeNumber (ohlcv, 2),
|
884
|
+
this.safeNumber (ohlcv, 3),
|
885
|
+
this.safeNumber (ohlcv, 4),
|
886
|
+
this.safeNumber (ohlcv, 5),
|
887
|
+
];
|
888
|
+
}
|
889
|
+
|
890
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
891
|
+
await this.loadMarkets ();
|
892
|
+
const market = this.market (symbol);
|
893
|
+
const request = {
|
894
|
+
'symbol': market['id'],
|
895
|
+
'interval': this.timeframes[timeframe],
|
896
|
+
};
|
897
|
+
if (since !== undefined) {
|
898
|
+
request['startTime'] = since;
|
899
|
+
}
|
900
|
+
if (limit !== undefined) {
|
901
|
+
request['limit'] = limit; // default 500, max 1000
|
902
|
+
}
|
903
|
+
const response = await this.publicGetV2Klines (this.extend (request, params));
|
904
|
+
//
|
905
|
+
// [
|
906
|
+
// [1590971040000,"0.02454","0.02456","0.02452","0.02456",249],
|
907
|
+
// [1590971100000,"0.02455","0.02457","0.02452","0.02456",300],
|
908
|
+
// [1590971160000,"0.02455","0.02456","0.02453","0.02454",286],
|
909
|
+
// ]
|
910
|
+
//
|
911
|
+
return this.parseOHLCVs (response, market, timeframe, since, limit);
|
912
|
+
}
|
913
|
+
|
914
|
+
parseTrade (trade, market = undefined) {
|
915
|
+
//
|
916
|
+
// fetchTrades (public aggregate trades)
|
917
|
+
//
|
918
|
+
// {
|
919
|
+
// "a":"1658318071", // Aggregate tradeId
|
920
|
+
// "p":"0.02476", // Price
|
921
|
+
// "q":"0.0", // Official doc says: "Quantity (should be ignored)"
|
922
|
+
// "T":"1591001423382", // Epoch timestamp in MS
|
923
|
+
// "m":false // Was the buyer the maker
|
924
|
+
// }
|
925
|
+
//
|
926
|
+
// createOrder fills (private)
|
927
|
+
//
|
928
|
+
// {
|
929
|
+
// "price": "9807.05",
|
930
|
+
// "qty": "0.01",
|
931
|
+
// "commission": "0",
|
932
|
+
// "commissionAsset": "dUSD"
|
933
|
+
// }
|
934
|
+
//
|
935
|
+
// fetchMyTrades
|
936
|
+
//
|
937
|
+
// {
|
938
|
+
// "symbol": "DOGE/USD",
|
939
|
+
// "id": "116046000",
|
940
|
+
// "orderId": "00000000-0000-0000-0000-000006dbb8ad",
|
941
|
+
// "price": "0.14094",
|
942
|
+
// "qty": "40.0",
|
943
|
+
// "commission": "0.01",
|
944
|
+
// "commissionAsset": "USD",
|
945
|
+
// "time": "1645283022351",
|
946
|
+
// "buyer": false,
|
947
|
+
// "maker": false,
|
948
|
+
// "isBuyer": false,
|
949
|
+
// "isMaker": false
|
950
|
+
// }
|
951
|
+
//
|
952
|
+
const timestamp = this.safeInteger2 (trade, 'T', 'time');
|
953
|
+
const priceString = this.safeString2 (trade, 'p', 'price');
|
954
|
+
const amountString = this.safeString2 (trade, 'q', 'qty');
|
955
|
+
const id = this.safeString2 (trade, 'a', 'id');
|
956
|
+
let side = undefined;
|
957
|
+
const orderId = this.safeString (trade, 'orderId');
|
958
|
+
let takerOrMaker = undefined;
|
959
|
+
if ('m' in trade) {
|
960
|
+
side = trade['m'] ? 'sell' : 'buy'; // this is reversed intentionally [TODO: needs reason to be mentioned]
|
961
|
+
takerOrMaker = 'taker'; // in public trades, it's always taker
|
962
|
+
} else if ('isBuyer' in trade) {
|
963
|
+
side = (trade['isBuyer']) ? 'buy' : 'sell'; // this is a true side
|
964
|
+
takerOrMaker = trade['isMaker'] ? 'maker' : 'taker';
|
965
|
+
}
|
966
|
+
let fee = undefined;
|
967
|
+
if ('commission' in trade) {
|
968
|
+
fee = {
|
969
|
+
'cost': this.safeString (trade, 'commission'),
|
970
|
+
'currency': this.safeCurrencyCode (this.safeString (trade, 'commissionAsset')),
|
971
|
+
};
|
972
|
+
}
|
973
|
+
const marketId = this.safeString (trade, 'symbol');
|
974
|
+
const symbol = this.safeSymbol (marketId, market);
|
975
|
+
return this.safeTrade ({
|
976
|
+
'id': id,
|
977
|
+
'order': orderId,
|
978
|
+
'timestamp': timestamp,
|
979
|
+
'datetime': this.iso8601 (timestamp),
|
980
|
+
'symbol': symbol,
|
981
|
+
'type': undefined,
|
982
|
+
'takerOrMaker': takerOrMaker,
|
983
|
+
'side': side,
|
984
|
+
'price': priceString,
|
985
|
+
'amount': amountString,
|
986
|
+
'cost': undefined,
|
987
|
+
'fee': fee,
|
988
|
+
'info': trade,
|
989
|
+
}, market);
|
990
|
+
}
|
991
|
+
|
992
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
993
|
+
await this.loadMarkets ();
|
994
|
+
const market = this.market (symbol);
|
995
|
+
const request = {
|
996
|
+
'symbol': market['id'],
|
997
|
+
// 'limit': 500, // default 500, max 1000
|
998
|
+
};
|
999
|
+
if (limit !== undefined) {
|
1000
|
+
request['limit'] = limit; // default 500, max 1000
|
1001
|
+
}
|
1002
|
+
if (since !== undefined) {
|
1003
|
+
request['startTime'] = since;
|
1004
|
+
}
|
1005
|
+
const response = await this.publicGetV2AggTrades (this.extend (request, params));
|
1006
|
+
//
|
1007
|
+
// [
|
1008
|
+
// {
|
1009
|
+
// "a":"1658318071", // Aggregate tradeId
|
1010
|
+
// "p":"0.02476", // Price
|
1011
|
+
// "q":"0.0", // Official doc says: "Quantity (should be ignored)"
|
1012
|
+
// "T":"1591001423382", // Epoch timestamp in MS
|
1013
|
+
// "m":false // Was the buyer the maker
|
1014
|
+
// },
|
1015
|
+
// ]
|
1016
|
+
//
|
1017
|
+
return this.parseTrades (response, market, since, limit);
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
parseOrder (order, market = undefined) {
|
1021
|
+
//
|
1022
|
+
// createOrder
|
1023
|
+
//
|
1024
|
+
// limit
|
1025
|
+
//
|
1026
|
+
// {
|
1027
|
+
// "symbol": "BTC/USD",
|
1028
|
+
// "orderId": "00000000-0000-0000-0000-000006eacaa0",
|
1029
|
+
// "transactTime": "1645281669295",
|
1030
|
+
// "price": "30000.00000000",
|
1031
|
+
// "origQty": "0.0002",
|
1032
|
+
// "executedQty": "0.0", // positive for BUY, negative for SELL
|
1033
|
+
// "status": "NEW",
|
1034
|
+
// "timeInForce": "GTC",
|
1035
|
+
// "type": "LIMIT",
|
1036
|
+
// "side": "BUY",
|
1037
|
+
// }
|
1038
|
+
//
|
1039
|
+
// market
|
1040
|
+
//
|
1041
|
+
// {
|
1042
|
+
// "symbol": "DOGE/USD",
|
1043
|
+
// "orderId": "00000000-0000-0000-0000-000006eab2ad",
|
1044
|
+
// "transactTime": "1645283022252",
|
1045
|
+
// "price": "0.14066000",
|
1046
|
+
// "origQty": "40",
|
1047
|
+
// "executedQty": "40.0", // positive for BUY, negative for SELL
|
1048
|
+
// "status": "FILLED",
|
1049
|
+
// "timeInForce": "FOK",
|
1050
|
+
// "type": "MARKET",
|
1051
|
+
// "side": "SELL",
|
1052
|
+
// "fills": [
|
1053
|
+
// {
|
1054
|
+
// "price": "0.14094",
|
1055
|
+
// "qty": "40.0",
|
1056
|
+
// "commission": "0",
|
1057
|
+
// "commissionAsset": "dUSD",
|
1058
|
+
// },
|
1059
|
+
// ],
|
1060
|
+
// }
|
1061
|
+
//
|
1062
|
+
// cancelOrder
|
1063
|
+
//
|
1064
|
+
// {
|
1065
|
+
// "symbol": "DOGE/USD",
|
1066
|
+
// "orderId": "00000000-0000-0003-0000-000006db714c",
|
1067
|
+
// "price": "0.13",
|
1068
|
+
// "origQty": "30.0",
|
1069
|
+
// "executedQty": "0.0",
|
1070
|
+
// "status": "CANCELED",
|
1071
|
+
// "timeInForce": "GTC",
|
1072
|
+
// "type": "LIMIT",
|
1073
|
+
// "side": "BUY",
|
1074
|
+
// }
|
1075
|
+
//
|
1076
|
+
// fetchOpenOrders
|
1077
|
+
//
|
1078
|
+
// {
|
1079
|
+
// "symbol": "DOGE/USD",
|
1080
|
+
// "orderId": "00000000-0000-0003-0000-000004bcc27a",
|
1081
|
+
// "price": "0.13",
|
1082
|
+
// "origQty": "39.0",
|
1083
|
+
// "executedQty": "0.0",
|
1084
|
+
// "status": "NEW",
|
1085
|
+
// "timeInForce": "GTC",
|
1086
|
+
// "type": "LIMIT",
|
1087
|
+
// "side": "BUY",
|
1088
|
+
// "time": "1645284216240",
|
1089
|
+
// "updateTime": "1645284216240",
|
1090
|
+
// "leverage": false, // whether it's swap or not
|
1091
|
+
// "working": true,
|
1092
|
+
// }
|
1093
|
+
//
|
1094
|
+
const marketId = this.safeString (order, 'symbol');
|
1095
|
+
const symbol = this.safeSymbol (marketId, market, '/');
|
1096
|
+
const id = this.safeString (order, 'orderId');
|
1097
|
+
const price = this.safeString (order, 'price');
|
1098
|
+
const amount = this.safeString (order, 'origQty');
|
1099
|
+
const filledRaw = this.safeString (order, 'executedQty');
|
1100
|
+
const filled = Precise.stringAbs (filledRaw);
|
1101
|
+
const status = this.parseOrderStatus (this.safeString (order, 'status'));
|
1102
|
+
const timeInForce = this.parseOrderTimeInForce (this.safeString (order, 'timeInForce'));
|
1103
|
+
const type = this.parseOrderType (this.safeString (order, 'type'));
|
1104
|
+
const side = this.parseOrderSide (this.safeString (order, 'side'));
|
1105
|
+
const timestamp = this.safeInteger2 (order, 'time', 'transactTime');
|
1106
|
+
const fills = this.safeValue (order, 'fills');
|
1107
|
+
return this.safeOrder ({
|
1108
|
+
'info': order,
|
1109
|
+
'id': id,
|
1110
|
+
'timestamp': timestamp,
|
1111
|
+
'datetime': this.iso8601 (timestamp),
|
1112
|
+
'lastTradeTimestamp': undefined,
|
1113
|
+
'symbol': symbol,
|
1114
|
+
'type': type,
|
1115
|
+
'timeInForce': timeInForce,
|
1116
|
+
'side': side,
|
1117
|
+
'price': price,
|
1118
|
+
'stopPrice': undefined,
|
1119
|
+
'amount': amount,
|
1120
|
+
'cost': undefined,
|
1121
|
+
'average': undefined,
|
1122
|
+
'filled': filled,
|
1123
|
+
'remaining': undefined,
|
1124
|
+
'status': status,
|
1125
|
+
'fee': undefined,
|
1126
|
+
'trades': fills,
|
1127
|
+
}, market);
|
1128
|
+
}
|
1129
|
+
|
1130
|
+
parseOrderStatus (status) {
|
1131
|
+
const statuses = {
|
1132
|
+
'NEW': 'open',
|
1133
|
+
'PARTIALLY_FILLED': 'open',
|
1134
|
+
'FILLED': 'closed',
|
1135
|
+
'CANCELED': 'canceled',
|
1136
|
+
'PENDING_CANCEL': 'canceling',
|
1137
|
+
'REJECTED': 'rejected',
|
1138
|
+
'EXPIRED': 'expired',
|
1139
|
+
};
|
1140
|
+
return this.safeString (statuses, status, status);
|
1141
|
+
}
|
1142
|
+
|
1143
|
+
parseOrderType (status) {
|
1144
|
+
const statuses = {
|
1145
|
+
'MARKET': 'market',
|
1146
|
+
'LIMIT': 'limit',
|
1147
|
+
'STOP': 'stop',
|
1148
|
+
// temporarily we remove custom mappings
|
1149
|
+
// 'LIMIT_MAKER': '',
|
1150
|
+
// 'STOP_LOSS': 'stop-loss',
|
1151
|
+
// 'STOP_LOSS_LIMIT': 'stop-limit',
|
1152
|
+
// 'TAKE_PROFIT': 'take-profit',
|
1153
|
+
// 'TAKE_PROFIT_LIMIT': 'take-profit',
|
1154
|
+
};
|
1155
|
+
return this.safeString (statuses, status, status);
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
parseOrderTimeInForce (status) {
|
1159
|
+
const statuses = {
|
1160
|
+
'GTC': 'GTC',
|
1161
|
+
'FOK': 'FOK',
|
1162
|
+
'IOC': 'IOC',
|
1163
|
+
};
|
1164
|
+
return this.safeString (statuses, status, status);
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
parseOrderSide (status) {
|
1168
|
+
const statuses = {
|
1169
|
+
'BUY': 'buy',
|
1170
|
+
'SELL': 'sell',
|
1171
|
+
};
|
1172
|
+
return this.safeString (statuses, status, status);
|
1173
|
+
}
|
1174
|
+
|
1175
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
1176
|
+
await this.loadMarkets ();
|
1177
|
+
const market = this.market (symbol);
|
1178
|
+
let accountId = undefined;
|
1179
|
+
if (market['margin']) {
|
1180
|
+
accountId = this.safeString (this.options, 'accountId');
|
1181
|
+
accountId = this.safeString (params, 'accountId', accountId);
|
1182
|
+
if (accountId === undefined) {
|
1183
|
+
throw new ArgumentsRequired (this.id + " createOrder() requires an accountId parameter or an exchange.options['accountId'] option for " + market['type'] + ' markets');
|
1184
|
+
}
|
1185
|
+
}
|
1186
|
+
const newOrderRespType = this.safeValue (this.options['newOrderRespType'], type, 'RESULT');
|
1187
|
+
const request = {
|
1188
|
+
'symbol': market['id'],
|
1189
|
+
'quantity': this.amountToPrecision (symbol, amount),
|
1190
|
+
'type': type.toUpperCase (),
|
1191
|
+
'side': side.toUpperCase (),
|
1192
|
+
'newOrderRespType': newOrderRespType, // 'RESULT' for full order or 'FULL' for order with fills
|
1193
|
+
// 'leverage': 1,
|
1194
|
+
// 'accountId': 5470306579272968, // required for leverage markets
|
1195
|
+
// 'takeProfit': '123.45',
|
1196
|
+
// 'stopLoss': '54.321',
|
1197
|
+
// 'guaranteedStopLoss': '54.321',
|
1198
|
+
};
|
1199
|
+
if (type === 'limit') {
|
1200
|
+
request['price'] = this.priceToPrecision (symbol, price);
|
1201
|
+
request['timeInForce'] = this.options['defaultTimeInForce'];
|
1202
|
+
} else {
|
1203
|
+
if (type === 'stop') {
|
1204
|
+
request['type'] = 'STOP';
|
1205
|
+
request['price'] = this.priceToPrecision (symbol, price);
|
1206
|
+
} else if (type === 'market') {
|
1207
|
+
const stopPrice = this.safeNumber (params, 'stopPrice');
|
1208
|
+
params = this.omit (params, 'stopPrice');
|
1209
|
+
if (stopPrice !== undefined) {
|
1210
|
+
request['type'] = 'STOP';
|
1211
|
+
request['price'] = this.priceToPrecision (symbol, stopPrice);
|
1212
|
+
}
|
1213
|
+
}
|
1214
|
+
}
|
1215
|
+
const response = await this.privatePostV2Order (this.extend (request, params));
|
1216
|
+
//
|
1217
|
+
// limit
|
1218
|
+
//
|
1219
|
+
// {
|
1220
|
+
// "symbol": "BTC/USD",
|
1221
|
+
// "orderId": "00000000-0000-0000-0000-000006eaaaa0",
|
1222
|
+
// "transactTime": "1645281669295",
|
1223
|
+
// "price": "30000.00000000",
|
1224
|
+
// "origQty": "0.0002",
|
1225
|
+
// "executedQty": "0.0", // positive for BUY, negative for SELL
|
1226
|
+
// "status": "NEW",
|
1227
|
+
// "timeInForce": "GTC",
|
1228
|
+
// "type": "LIMIT",
|
1229
|
+
// "side": "BUY",
|
1230
|
+
// }
|
1231
|
+
//
|
1232
|
+
// market
|
1233
|
+
//
|
1234
|
+
// {
|
1235
|
+
// "symbol": "DOGE/USD",
|
1236
|
+
// "orderId": "00000000-0000-0000-0000-000006eab8ad",
|
1237
|
+
// "transactTime": "1645283022252",
|
1238
|
+
// "price": "0.14066000",
|
1239
|
+
// "origQty": "40",
|
1240
|
+
// "executedQty": "40.0", // positive for BUY, negative for SELL
|
1241
|
+
// "status": "FILLED",
|
1242
|
+
// "timeInForce": "FOK",
|
1243
|
+
// "type": "MARKET",
|
1244
|
+
// "side": "BUY",
|
1245
|
+
// "fills": [
|
1246
|
+
// {
|
1247
|
+
// "price": "0.14094",
|
1248
|
+
// "qty": "40.0",
|
1249
|
+
// "commission": "0",
|
1250
|
+
// "commissionAsset": "dUSD"
|
1251
|
+
// }
|
1252
|
+
// ]
|
1253
|
+
// }
|
1254
|
+
//
|
1255
|
+
return this.parseOrder (response, market);
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
1259
|
+
await this.loadMarkets ();
|
1260
|
+
let market = undefined;
|
1261
|
+
const request = {};
|
1262
|
+
if (symbol !== undefined) {
|
1263
|
+
market = this.market (symbol);
|
1264
|
+
request['symbol'] = market['id'];
|
1265
|
+
} else if (this.options['warnOnFetchOpenOrdersWithoutSymbol']) {
|
1266
|
+
const symbols = this.symbols;
|
1267
|
+
const numSymbols = symbols.length;
|
1268
|
+
const fetchOpenOrdersRateLimit = parseInt (numSymbols / 2);
|
1269
|
+
throw new ExchangeError (this.id + ' fetchOpenOrders() WARNING: fetching open orders without specifying a symbol is rate-limited to one call per ' + fetchOpenOrdersRateLimit.toString () + ' seconds. Do not call this method frequently to avoid ban. Set ' + this.id + '.options["warnOnFetchOpenOrdersWithoutSymbol"] = false to suppress this warning message.');
|
1270
|
+
}
|
1271
|
+
const response = await this.privateGetV2OpenOrders (this.extend (request, params));
|
1272
|
+
//
|
1273
|
+
// [
|
1274
|
+
// {
|
1275
|
+
// "symbol": "DOGE/USD",
|
1276
|
+
// "orderId": "00000000-0000-0003-0000-000004bac57a",
|
1277
|
+
// "price": "0.13",
|
1278
|
+
// "origQty": "39.0",
|
1279
|
+
// "executedQty": "0.0", // positive for BUY, negative for SELL
|
1280
|
+
// "status": "NEW",
|
1281
|
+
// "timeInForce": "GTC",
|
1282
|
+
// "type": "LIMIT",
|
1283
|
+
// "side": "BUY",
|
1284
|
+
// "time": "1645284216240",
|
1285
|
+
// "updateTime": "1645284216240",
|
1286
|
+
// "leverage": false,
|
1287
|
+
// "working": true
|
1288
|
+
// },
|
1289
|
+
// ]
|
1290
|
+
//
|
1291
|
+
return this.parseOrders (response, market, since, limit, params);
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
1295
|
+
if (symbol === undefined) {
|
1296
|
+
throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
|
1297
|
+
}
|
1298
|
+
await this.loadMarkets ();
|
1299
|
+
const market = this.market (symbol);
|
1300
|
+
const origClientOrderId = this.safeValue (params, 'origClientOrderId');
|
1301
|
+
const request = {
|
1302
|
+
'symbol': market['id'],
|
1303
|
+
// 'orderId': parseInt (id),
|
1304
|
+
// 'origClientOrderId': id,
|
1305
|
+
};
|
1306
|
+
if (origClientOrderId === undefined) {
|
1307
|
+
request['orderId'] = id;
|
1308
|
+
} else {
|
1309
|
+
request['origClientOrderId'] = origClientOrderId;
|
1310
|
+
}
|
1311
|
+
const response = await this.privateDeleteV2Order (this.extend (request, params));
|
1312
|
+
//
|
1313
|
+
// {
|
1314
|
+
// "symbol": "DOGE/USD",
|
1315
|
+
// "orderId": "00000000-0000-0003-0000-000006db764c",
|
1316
|
+
// "price": "0.13",
|
1317
|
+
// "origQty": "30.0",
|
1318
|
+
// "executedQty": "0.0", // positive for BUY, negative for SELL
|
1319
|
+
// "status": "CANCELED",
|
1320
|
+
// "timeInForce": "GTC",
|
1321
|
+
// "type": "LIMIT",
|
1322
|
+
// "side": "BUY",
|
1323
|
+
// }
|
1324
|
+
//
|
1325
|
+
return this.parseOrder (response, market);
|
1326
|
+
}
|
1327
|
+
|
1328
|
+
async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
1329
|
+
if (symbol === undefined) {
|
1330
|
+
throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a symbol argument');
|
1331
|
+
}
|
1332
|
+
await this.loadMarkets ();
|
1333
|
+
const market = this.market (symbol);
|
1334
|
+
const request = {
|
1335
|
+
'symbol': market['id'],
|
1336
|
+
};
|
1337
|
+
if (limit !== undefined) {
|
1338
|
+
request['limit'] = limit;
|
1339
|
+
}
|
1340
|
+
const response = await this.privateGetV2MyTrades (this.extend (request, params));
|
1341
|
+
//
|
1342
|
+
// [
|
1343
|
+
// {
|
1344
|
+
// "symbol": "DOGE/USD",
|
1345
|
+
// "id": "116046000",
|
1346
|
+
// "orderId": "00000000-0000-0000-0000-000006dbb8ad",
|
1347
|
+
// "price": "0.14094",
|
1348
|
+
// "qty": "40.0",
|
1349
|
+
// "commission": "0.01",
|
1350
|
+
// "commissionAsset": "USD",
|
1351
|
+
// "time": "1645283022351",
|
1352
|
+
// "buyer": false,
|
1353
|
+
// "maker": false,
|
1354
|
+
// "isBuyer": false,
|
1355
|
+
// "isMaker": false
|
1356
|
+
// },
|
1357
|
+
// ]
|
1358
|
+
//
|
1359
|
+
return this.parseTrades (response, market, since, limit);
|
1360
|
+
}
|
1361
|
+
|
1362
|
+
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
1363
|
+
return await this.fetchTransactionsByMethod ('privateGetV2Deposits', code, since, limit, params);
|
1364
|
+
}
|
1365
|
+
|
1366
|
+
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
1367
|
+
return await this.fetchTransactionsByMethod ('privateGetV2Withdrawals', code, since, limit, params);
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
async fetchTransactions (code = undefined, since = undefined, limit = undefined, params = {}) {
|
1371
|
+
return await this.fetchTransactionsByMethod ('privateGetV2Transactions', code, since, limit, params);
|
1372
|
+
}
|
1373
|
+
|
1374
|
+
async fetchTransactionsByMethod (method, code = undefined, since = undefined, limit = undefined, params = {}) {
|
1375
|
+
await this.loadMarkets ();
|
1376
|
+
const request = {};
|
1377
|
+
let currency = undefined;
|
1378
|
+
if (code !== undefined) {
|
1379
|
+
currency = this.currency (code);
|
1380
|
+
}
|
1381
|
+
if (since !== undefined) {
|
1382
|
+
request['startTime'] = since;
|
1383
|
+
}
|
1384
|
+
if (limit !== undefined) {
|
1385
|
+
request['limit'] = limit;
|
1386
|
+
}
|
1387
|
+
const response = await this[method] (this.extend (request, params));
|
1388
|
+
//
|
1389
|
+
// [
|
1390
|
+
// {
|
1391
|
+
// "id": "616769213",
|
1392
|
+
// "balance": "2.088",
|
1393
|
+
// "amount": "1.304", // negative for 'withdrawal'
|
1394
|
+
// "currency": "CAKE",
|
1395
|
+
// "type": "deposit",
|
1396
|
+
// "timestamp": "1645282121023",
|
1397
|
+
// "paymentMethod": "BLOCKCHAIN",
|
1398
|
+
// "blockchainTransactionHash": "0x57c68c1f2ae74d5eda5a2a00516361d241a5c9e1ee95bf32573523857c38c112",
|
1399
|
+
// "status": "PROCESSED",
|
1400
|
+
// "commission": "0.14", // this property only exists in withdrawal
|
1401
|
+
// },
|
1402
|
+
// ]
|
1403
|
+
//
|
1404
|
+
return this.parseTransactions (response, currency, since, limit, params);
|
1405
|
+
}
|
1406
|
+
|
1407
|
+
parseTransaction (transaction, currency = undefined) {
|
1408
|
+
const id = this.safeString (transaction, 'id');
|
1409
|
+
const txHash = this.safeString (transaction, 'blockchainTransactionHash');
|
1410
|
+
const amount = this.safeNumber (transaction, 'amount');
|
1411
|
+
const timestamp = this.safeInteger (transaction, 'timestamp');
|
1412
|
+
const currencyId = this.safeString (transaction, 'currency');
|
1413
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
1414
|
+
const state = this.parseTransactionStatus (this.safeString (transaction, 'state'));
|
1415
|
+
const type = this.parseTransactionType (this.safeString (transaction, 'type'));
|
1416
|
+
const feeCost = this.safeString (transaction, 'commission');
|
1417
|
+
let fee = undefined;
|
1418
|
+
if (feeCost !== undefined) {
|
1419
|
+
fee = { 'currency': code, 'cost': feeCost };
|
1420
|
+
}
|
1421
|
+
const result = {
|
1422
|
+
'id': id,
|
1423
|
+
'txid': txHash,
|
1424
|
+
'timestamp': timestamp,
|
1425
|
+
'datetime': this.iso8601 (timestamp),
|
1426
|
+
'network': undefined,
|
1427
|
+
'addressFrom': undefined,
|
1428
|
+
'address': undefined,
|
1429
|
+
'addressTo': undefined,
|
1430
|
+
'tagFrom': undefined,
|
1431
|
+
'tag': undefined,
|
1432
|
+
'tagTo': undefined,
|
1433
|
+
'type': type,
|
1434
|
+
'amount': amount,
|
1435
|
+
'currency': code,
|
1436
|
+
'status': state,
|
1437
|
+
'updated': undefined,
|
1438
|
+
'comment': undefined,
|
1439
|
+
'fee': fee,
|
1440
|
+
'info': transaction,
|
1441
|
+
};
|
1442
|
+
return result;
|
1443
|
+
}
|
1444
|
+
|
1445
|
+
parseTransactionStatus (status) {
|
1446
|
+
const statuses = {
|
1447
|
+
'APPROVAL': 'pending',
|
1448
|
+
'PROCESSED': 'ok',
|
1449
|
+
};
|
1450
|
+
return this.safeString (statuses, status, status);
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
parseTransactionType (type) {
|
1454
|
+
const types = {
|
1455
|
+
'deposit': 'deposit',
|
1456
|
+
'withdrawal': 'withdrawal',
|
1457
|
+
};
|
1458
|
+
return this.safeString (types, type, type);
|
1459
|
+
}
|
1460
|
+
|
1461
|
+
async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
|
1462
|
+
await this.loadMarkets ();
|
1463
|
+
const request = {};
|
1464
|
+
let currency = undefined;
|
1465
|
+
if (code !== undefined) {
|
1466
|
+
currency = this.currency (code);
|
1467
|
+
}
|
1468
|
+
if (since !== undefined) {
|
1469
|
+
request['startTime'] = since;
|
1470
|
+
}
|
1471
|
+
if (limit !== undefined) {
|
1472
|
+
request['limit'] = limit;
|
1473
|
+
}
|
1474
|
+
const response = await this.privateGetV2Ledger (this.extend (request, params));
|
1475
|
+
// in the below example, first item expresses withdrawal/deposit type, second example expresses trade
|
1476
|
+
//
|
1477
|
+
// [
|
1478
|
+
// {
|
1479
|
+
// "id": "619031398",
|
1480
|
+
// "balance": "0.0",
|
1481
|
+
// "amount": "-1.088",
|
1482
|
+
// "currency": "CAKE",
|
1483
|
+
// "type": "withdrawal",
|
1484
|
+
// "timestamp": "1645460496425",
|
1485
|
+
// "commission": "0.13",
|
1486
|
+
// "paymentMethod": "BLOCKCHAIN", // present in withdrawal/deposit
|
1487
|
+
// "blockchainTransactionHash": "0x400ac905557c3d34638b1c60eba110b3ee0f97f4eb0f7318015ab76e7f16b7d6", // present in withdrawal/deposit
|
1488
|
+
// "status": "PROCESSED"
|
1489
|
+
// },
|
1490
|
+
// {
|
1491
|
+
// "id": "619031034",
|
1492
|
+
// "balance": "8.17223588",
|
1493
|
+
// "amount": "-0.01326294",
|
1494
|
+
// "currency": "USD",
|
1495
|
+
// "type": "exchange_commission",
|
1496
|
+
// "timestamp": "1645460461235",
|
1497
|
+
// "commission": "0.01326294",
|
1498
|
+
// "status": "PROCESSED"
|
1499
|
+
// },
|
1500
|
+
// ]
|
1501
|
+
//
|
1502
|
+
return this.parseLedger (response, currency, since, limit);
|
1503
|
+
}
|
1504
|
+
|
1505
|
+
parseLedgerEntry (item, currency = undefined) {
|
1506
|
+
const id = this.safeString (item, 'id');
|
1507
|
+
const amountString = this.safeString (item, 'amount');
|
1508
|
+
const amount = Precise.stringAbs (amountString);
|
1509
|
+
const timestamp = this.safeInteger (item, 'timestamp');
|
1510
|
+
const currencyId = this.safeString (item, 'currency');
|
1511
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
1512
|
+
const feeCost = this.safeString (item, 'commission');
|
1513
|
+
let fee = undefined;
|
1514
|
+
if (feeCost !== undefined) {
|
1515
|
+
fee = { 'currency': code, 'cost': feeCost };
|
1516
|
+
}
|
1517
|
+
const direction = Precise.stringLt (amountString, '0') ? 'out' : 'in';
|
1518
|
+
const result = {
|
1519
|
+
'id': id,
|
1520
|
+
'timestamp': timestamp,
|
1521
|
+
'datetime': this.iso8601 (timestamp),
|
1522
|
+
'direction': direction,
|
1523
|
+
'account': undefined,
|
1524
|
+
'referenceId': this.safeString (item, 'blockchainTransactionHash'),
|
1525
|
+
'referenceAccount': undefined,
|
1526
|
+
'type': this.parseLedgerEntryType (this.safeString (item, 'type')),
|
1527
|
+
'currency': code,
|
1528
|
+
'amount': amount,
|
1529
|
+
'before': undefined,
|
1530
|
+
'after': this.safeString (item, 'balance'),
|
1531
|
+
'status': this.parseLedgerEntryStatus (this.safeString (item, 'status')),
|
1532
|
+
'fee': fee,
|
1533
|
+
'info': item,
|
1534
|
+
};
|
1535
|
+
return result;
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
parseLedgerEntryStatus (status) {
|
1539
|
+
const statuses = {
|
1540
|
+
'APPROVAL': 'pending',
|
1541
|
+
'PROCESSED': 'ok',
|
1542
|
+
'CANCELLED': 'canceled',
|
1543
|
+
};
|
1544
|
+
return this.safeString (statuses, status, status);
|
1545
|
+
}
|
1546
|
+
|
1547
|
+
parseLedgerEntryType (type) {
|
1548
|
+
const types = {
|
1549
|
+
'deposit': 'transaction',
|
1550
|
+
'withdrawal': 'transaction',
|
1551
|
+
'exchange_commission': 'fee',
|
1552
|
+
};
|
1553
|
+
return this.safeString (types, type, type);
|
1554
|
+
}
|
1555
|
+
|
1556
|
+
async fetchLeverage (symbol, params = {}) {
|
1557
|
+
await this.loadMarkets ();
|
1558
|
+
const market = this.market (symbol);
|
1559
|
+
const request = {
|
1560
|
+
'symbol': market['id'],
|
1561
|
+
};
|
1562
|
+
const response = await this.privateGetV2LeverageSettings (this.extend (request, params));
|
1563
|
+
//
|
1564
|
+
// {
|
1565
|
+
// "values": [ 1, 2, 5, 10, ],
|
1566
|
+
// "value": "10",
|
1567
|
+
// }
|
1568
|
+
//
|
1569
|
+
return this.safeNumber (response, 'value');
|
1570
|
+
}
|
1571
|
+
|
1572
|
+
async fetchDepositAddress (code, params = {}) {
|
1573
|
+
await this.loadMarkets ();
|
1574
|
+
const currency = this.currency (code);
|
1575
|
+
const request = {
|
1576
|
+
'coin': currency['id'],
|
1577
|
+
};
|
1578
|
+
const response = await this.privateGetV2DepositAddress (this.extend (request, params));
|
1579
|
+
//
|
1580
|
+
// { "address":"0x97d64eb014ac779194991e7264f01c74c90327f0" }
|
1581
|
+
//
|
1582
|
+
return this.parseDepositAddress (response, currency);
|
1583
|
+
}
|
1584
|
+
|
1585
|
+
parseDepositAddress (depositAddress, currency = undefined) {
|
1586
|
+
const address = this.safeString (depositAddress, 'address');
|
1587
|
+
this.checkAddress (address);
|
1588
|
+
currency = this.safeCurrency (undefined, currency);
|
1589
|
+
return {
|
1590
|
+
'currency': currency['code'],
|
1591
|
+
'address': address,
|
1592
|
+
'tag': undefined,
|
1593
|
+
'network': undefined,
|
1594
|
+
'info': depositAddress,
|
1595
|
+
};
|
1596
|
+
}
|
1597
|
+
|
1598
|
+
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
1599
|
+
let url = this.urls['api'][api] + '/' + path;
|
1600
|
+
if (path === 'historicalTrades') {
|
1601
|
+
headers = {
|
1602
|
+
'X-MBX-APIKEY': this.apiKey,
|
1603
|
+
};
|
1604
|
+
}
|
1605
|
+
if (api === 'private') {
|
1606
|
+
this.checkRequiredCredentials ();
|
1607
|
+
let query = this.urlencode (this.extend ({
|
1608
|
+
'timestamp': this.nonce (),
|
1609
|
+
'recvWindow': this.options['recvWindow'],
|
1610
|
+
}, params));
|
1611
|
+
const signature = this.hmac (this.encode (query), this.encode (this.secret));
|
1612
|
+
query += '&' + 'signature=' + signature;
|
1613
|
+
headers = {
|
1614
|
+
'X-MBX-APIKEY': this.apiKey,
|
1615
|
+
};
|
1616
|
+
if ((method === 'GET') || (method === 'DELETE')) {
|
1617
|
+
url += '?' + query;
|
1618
|
+
} else {
|
1619
|
+
body = query;
|
1620
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
1621
|
+
}
|
1622
|
+
} else {
|
1623
|
+
if (Object.keys (params).length) {
|
1624
|
+
url += '?' + this.urlencode (params);
|
1625
|
+
}
|
1626
|
+
}
|
1627
|
+
url = this.implodeHostname (url);
|
1628
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
1629
|
+
}
|
1630
|
+
|
1631
|
+
async fetchPositions (symbols = undefined, params = {}) {
|
1632
|
+
await this.loadMarkets ();
|
1633
|
+
const response = await this.privateGetV2TradingPositions (params);
|
1634
|
+
//
|
1635
|
+
// {
|
1636
|
+
// "positions": [
|
1637
|
+
// {
|
1638
|
+
// "accountId": "109698017416453793",
|
1639
|
+
// "id": "00a18490-0079-54c4-0000-0000803e73d3",
|
1640
|
+
// "instrumentId": "45463225268524228",
|
1641
|
+
// "orderId": "00a18490-0079-54c4-0000-0000803e73d2",
|
1642
|
+
// "openQuantity": "13.6",
|
1643
|
+
// "openPrice": "0.75724",
|
1644
|
+
// "closeQuantity": "0.0",
|
1645
|
+
// "closePrice": "0",
|
1646
|
+
// "rpl": "-0.007723848",
|
1647
|
+
// "rplConverted": "0",
|
1648
|
+
// "upl": "-0.006664",
|
1649
|
+
// "uplConverted": "-0.006664",
|
1650
|
+
// "swap": "0",
|
1651
|
+
// "swapConverted": "0",
|
1652
|
+
// "fee": "-0.007723848",
|
1653
|
+
// "dividend": "0",
|
1654
|
+
// "margin": "0.2",
|
1655
|
+
// "state": "ACTIVE",
|
1656
|
+
// "currency": "USD",
|
1657
|
+
// "createdTimestamp": "1645473877236",
|
1658
|
+
// "openTimestamp": "1645473877193",
|
1659
|
+
// "type": "NET",
|
1660
|
+
// "cost": "2.0583600",
|
1661
|
+
// "symbol": "XRP/USD_LEVERAGE"
|
1662
|
+
// }
|
1663
|
+
// ]
|
1664
|
+
// }
|
1665
|
+
//
|
1666
|
+
const data = this.safeValue (response, 'positions', []);
|
1667
|
+
return this.parsePositions (data);
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
parsePositions (positions) {
|
1671
|
+
const result = [];
|
1672
|
+
for (let i = 0; i < positions.length; i++) {
|
1673
|
+
result.push (this.parsePosition (positions[i]));
|
1674
|
+
}
|
1675
|
+
return result;
|
1676
|
+
}
|
1677
|
+
|
1678
|
+
parsePosition (position, market = undefined) {
|
1679
|
+
market = this.safeMarket (this.safeString (position, 'symbol'), market);
|
1680
|
+
const symbol = market['symbol'];
|
1681
|
+
const timestamp = this.safeNumber (position, 'createdTimestamp');
|
1682
|
+
const quantityRaw = this.safeString (position, 'openQuantity');
|
1683
|
+
const side = Precise.stringGt (quantityRaw, '0') ? 'long' : 'short';
|
1684
|
+
const quantity = Precise.stringAbs (quantityRaw);
|
1685
|
+
const entryPrice = this.safeNumber (position, 'openPrice');
|
1686
|
+
const unrealizedProfit = this.safeNumber (position, 'upl');
|
1687
|
+
const marginCoeff = this.safeString (position, 'margin');
|
1688
|
+
const leverage = Precise.stringDiv ('1', marginCoeff);
|
1689
|
+
return {
|
1690
|
+
'symbol': symbol,
|
1691
|
+
'timestamp': timestamp,
|
1692
|
+
'datetime': this.iso8601 (timestamp),
|
1693
|
+
'contracts': this.parseNumber (quantity),
|
1694
|
+
'contractSize': undefined,
|
1695
|
+
'entryPrice': entryPrice,
|
1696
|
+
'collateral': undefined,
|
1697
|
+
'side': side,
|
1698
|
+
// 'realizedProfit': this.safeNumber (position, 'rpl'),
|
1699
|
+
'unrealizedProfit': unrealizedProfit,
|
1700
|
+
'leverage': leverage,
|
1701
|
+
'percentage': undefined,
|
1702
|
+
'marginType': undefined,
|
1703
|
+
'notional': undefined,
|
1704
|
+
'markPrice': undefined,
|
1705
|
+
'liquidationPrice': undefined,
|
1706
|
+
'initialMargin': undefined,
|
1707
|
+
'initialMarginPercentage': undefined,
|
1708
|
+
'maintenanceMargin': this.parseNumber (marginCoeff),
|
1709
|
+
'maintenanceMarginPercentage': undefined,
|
1710
|
+
'marginRatio': undefined,
|
1711
|
+
'info': position,
|
1712
|
+
};
|
1713
|
+
}
|
1714
|
+
|
1715
|
+
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
1716
|
+
if ((httpCode === 418) || (httpCode === 429)) {
|
1717
|
+
throw new DDoSProtection (this.id + ' ' + httpCode.toString () + ' ' + reason + ' ' + body);
|
1718
|
+
}
|
1719
|
+
// error response in a form: { "code": -1013, "msg": "Invalid quantity." }
|
1720
|
+
// following block cointains legacy checks against message patterns in "msg" property
|
1721
|
+
// will switch "code" checks eventually, when we know all of them
|
1722
|
+
if (httpCode >= 400) {
|
1723
|
+
if (body.indexOf ('Price * QTY is zero or less') >= 0) {
|
1724
|
+
throw new InvalidOrder (this.id + ' order cost = amount * price is zero or less ' + body);
|
1725
|
+
}
|
1726
|
+
if (body.indexOf ('LOT_SIZE') >= 0) {
|
1727
|
+
throw new InvalidOrder (this.id + ' order amount should be evenly divisible by lot size ' + body);
|
1728
|
+
}
|
1729
|
+
if (body.indexOf ('PRICE_FILTER') >= 0) {
|
1730
|
+
throw new InvalidOrder (this.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) ' + body);
|
1731
|
+
}
|
1732
|
+
}
|
1733
|
+
if (response === undefined) {
|
1734
|
+
return; // fallback to default error handler
|
1735
|
+
}
|
1736
|
+
//
|
1737
|
+
// {"code":-1128,"msg":"Combination of optional parameters invalid."}
|
1738
|
+
//
|
1739
|
+
const errorCode = this.safeString (response, 'code');
|
1740
|
+
if ((errorCode !== undefined) && (errorCode !== '0')) {
|
1741
|
+
const feedback = this.id + ' ' + this.json (response);
|
1742
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], errorCode, feedback);
|
1743
|
+
const message = this.safeString (response, 'msg');
|
1744
|
+
this.throwBroadlyMatchedException (this.exceptions['broad'], message, feedback);
|
1745
|
+
throw new ExchangeError (feedback);
|
1746
|
+
}
|
1747
|
+
}
|
1748
|
+
};
|