ccxt 4.3.18 → 4.3.19
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/README.md +7 -5
- package/dist/cjs/ccxt.js +6 -1
- package/dist/cjs/src/abstract/woofipro.js +9 -0
- package/dist/cjs/src/ascendex.js +3 -4
- package/dist/cjs/src/base/Exchange.js +42 -2
- package/dist/cjs/src/base/functions/crypto.js +10 -3
- package/dist/cjs/src/base/functions/encode.js +6 -3
- package/dist/cjs/src/base/functions/number.js +8 -5
- package/dist/cjs/src/base/functions/rsa.js +5 -5
- package/dist/cjs/src/bigone.js +1 -1
- package/dist/cjs/src/bitfinex.js +25 -1
- package/dist/cjs/src/bitfinex2.js +59 -51
- package/dist/cjs/src/bitget.js +1 -5
- package/dist/cjs/src/bitmart.js +3 -3
- package/dist/cjs/src/bitstamp.js +1 -3
- package/dist/cjs/src/bybit.js +1 -0
- package/dist/cjs/src/coinex.js +321 -537
- package/dist/cjs/src/coinlist.js +1 -2
- package/dist/cjs/src/deribit.js +1 -1
- package/dist/cjs/src/hollaex.js +3 -3
- package/dist/cjs/src/indodax.js +1 -1
- package/dist/cjs/src/latoken.js +1 -1
- package/dist/cjs/src/mexc.js +1 -1
- package/dist/cjs/src/novadax.js +0 -1
- package/dist/cjs/src/okx.js +17 -0
- package/dist/cjs/src/poloniex.js +1 -2
- package/dist/cjs/src/pro/bitget.js +136 -192
- package/dist/cjs/src/pro/coinbaseinternational.js +9 -1
- package/dist/cjs/src/pro/okx.js +85 -0
- package/dist/cjs/src/pro/woofipro.js +1263 -0
- package/dist/cjs/src/wavesexchange.js +2 -2
- package/dist/cjs/src/woo.js +17 -3
- package/dist/cjs/src/woofipro.js +2698 -0
- package/js/ccxt.d.ts +8 -2
- package/js/ccxt.js +6 -2
- package/js/src/abstract/bybit.d.ts +1 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/abstract/woofipro.d.ts +122 -0
- package/js/src/abstract/woofipro.js +11 -0
- package/js/src/ace.d.ts +2 -2
- package/js/src/ascendex.d.ts +5 -15
- package/js/src/ascendex.js +3 -4
- package/js/src/base/Exchange.d.ts +26 -17
- package/js/src/base/Exchange.js +42 -2
- package/js/src/base/functions/crypto.d.ts +1 -1
- package/js/src/base/functions/crypto.js +10 -3
- package/js/src/base/functions/encode.d.ts +1 -1
- package/js/src/base/functions/encode.js +6 -3
- package/js/src/base/functions/number.d.ts +1 -1
- package/js/src/base/functions/number.js +8 -5
- package/js/src/base/functions/rsa.js +6 -6
- package/js/src/base/types.d.ts +4 -0
- package/js/src/bigone.d.ts +4 -14
- package/js/src/bigone.js +1 -1
- package/js/src/binance.d.ts +13 -71
- package/js/src/binancecoinm.d.ts +2 -22
- package/js/src/binanceusdm.d.ts +2 -22
- package/js/src/bingx.d.ts +4 -14
- package/js/src/bit2c.d.ts +2 -2
- package/js/src/bitbank.d.ts +2 -2
- package/js/src/bitbns.d.ts +2 -2
- package/js/src/bitfinex.d.ts +6 -16
- package/js/src/bitfinex.js +25 -1
- package/js/src/bitfinex2.d.ts +6 -16
- package/js/src/bitfinex2.js +59 -51
- package/js/src/bitflyer.d.ts +2 -2
- package/js/src/bitget.d.ts +7 -17
- package/js/src/bitget.js +1 -5
- package/js/src/bithumb.d.ts +3 -3
- package/js/src/bitmart.d.ts +5 -14
- package/js/src/bitmart.js +3 -3
- package/js/src/bitmex.d.ts +4 -4
- package/js/src/bitopro.d.ts +2 -2
- package/js/src/bitrue.d.ts +5 -5
- package/js/src/bitso.d.ts +2 -2
- package/js/src/bitstamp.d.ts +3 -3
- package/js/src/bitstamp.js +1 -3
- package/js/src/bitteam.d.ts +2 -2
- package/js/src/bitvavo.d.ts +5 -5
- package/js/src/bl3p.d.ts +2 -2
- package/js/src/blockchaincom.d.ts +2 -2
- package/js/src/blofin.d.ts +4 -14
- package/js/src/btcalpha.d.ts +2 -2
- package/js/src/btcbox.d.ts +2 -2
- package/js/src/btcmarkets.d.ts +2 -2
- package/js/src/btcturk.d.ts +2 -2
- package/js/src/bybit.d.ts +8 -56
- package/js/src/bybit.js +1 -0
- package/js/src/cex.d.ts +2 -2
- package/js/src/coinbase.d.ts +4 -4
- package/js/src/coinbasepro.d.ts +3 -3
- package/js/src/coincheck.d.ts +2 -2
- package/js/src/coinex.d.ts +6 -16
- package/js/src/coinex.js +321 -537
- package/js/src/coinlist.d.ts +5 -15
- package/js/src/coinlist.js +1 -2
- package/js/src/coinmate.d.ts +2 -2
- package/js/src/coinmetro.d.ts +3 -3
- package/js/src/coinone.d.ts +2 -2
- package/js/src/coinsph.d.ts +2 -2
- package/js/src/coinspot.d.ts +2 -2
- package/js/src/cryptocom.d.ts +2 -2
- package/js/src/currencycom.d.ts +3 -3
- package/js/src/delta.d.ts +5 -43
- package/js/src/deribit.d.ts +7 -55
- package/js/src/deribit.js +1 -1
- package/js/src/digifinex.d.ts +5 -15
- package/js/src/exmo.d.ts +2 -2
- package/js/src/gate.d.ts +6 -54
- package/js/src/gemini.d.ts +2 -2
- package/js/src/hitbtc.d.ts +4 -14
- package/js/src/hollaex.d.ts +3 -3
- package/js/src/hollaex.js +3 -3
- package/js/src/htx.d.ts +4 -14
- package/js/src/huobijp.d.ts +4 -4
- package/js/src/hyperliquid.d.ts +1 -1
- package/js/src/idex.d.ts +3 -3
- package/js/src/independentreserve.d.ts +2 -2
- package/js/src/indodax.d.ts +2 -2
- package/js/src/indodax.js +1 -1
- package/js/src/kraken.d.ts +4 -14
- package/js/src/krakenfutures.d.ts +4 -14
- package/js/src/kucoin.d.ts +5 -15
- package/js/src/kucoinfutures.d.ts +4 -14
- package/js/src/kuna.d.ts +2 -2
- package/js/src/latoken.d.ts +5 -15
- package/js/src/latoken.js +1 -1
- package/js/src/lbank.d.ts +2 -2
- package/js/src/luno.d.ts +2 -2
- package/js/src/lykke.d.ts +2 -2
- package/js/src/mercado.d.ts +2 -2
- package/js/src/mexc.d.ts +8 -28
- package/js/src/mexc.js +1 -1
- package/js/src/ndax.d.ts +2 -2
- package/js/src/novadax.d.ts +4 -15
- package/js/src/novadax.js +0 -1
- package/js/src/okcoin.d.ts +4 -14
- package/js/src/okx.d.ts +10 -68
- package/js/src/okx.js +17 -0
- package/js/src/onetrading.d.ts +2 -2
- package/js/src/paymium.d.ts +4 -14
- package/js/src/phemex.d.ts +5 -15
- package/js/src/poloniex.d.ts +3 -13
- package/js/src/poloniex.js +1 -2
- package/js/src/poloniexfutures.d.ts +2 -2
- package/js/src/pro/bitget.js +137 -193
- package/js/src/pro/coinbaseinternational.d.ts +3 -3
- package/js/src/pro/coinbaseinternational.js +9 -1
- package/js/src/pro/okx.d.ts +4 -1
- package/js/src/pro/okx.js +85 -0
- package/js/src/pro/woofipro.d.ts +47 -0
- package/js/src/pro/woofipro.js +1264 -0
- package/js/src/probit.d.ts +3 -3
- package/js/src/timex.d.ts +2 -2
- package/js/src/tokocrypto.d.ts +3 -3
- package/js/src/upbit.d.ts +2 -2
- package/js/src/wavesexchange.d.ts +3 -3
- package/js/src/wavesexchange.js +2 -2
- package/js/src/wazirx.d.ts +2 -2
- package/js/src/whitebit.d.ts +3 -13
- package/js/src/woo.d.ts +7 -17
- package/js/src/woo.js +17 -3
- package/js/src/woofipro.d.ts +131 -0
- package/js/src/woofipro.js +2699 -0
- package/js/src/yobit.d.ts +2 -2
- package/js/src/zaif.d.ts +2 -2
- package/js/src/zonda.d.ts +4 -14
- package/package.json +1 -1
|
@@ -0,0 +1,2698 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var woofipro$1 = require('./abstract/woofipro.js');
|
|
4
|
+
var errors = require('./base/errors.js');
|
|
5
|
+
var number = require('./base/functions/number.js');
|
|
6
|
+
var Precise = require('./base/Precise.js');
|
|
7
|
+
var crypto = require('./base/functions/crypto.js');
|
|
8
|
+
var ed25519 = require('./static_dependencies/noble-curves/ed25519.js');
|
|
9
|
+
var sha3 = require('./static_dependencies/noble-hashes/sha3.js');
|
|
10
|
+
var secp256k1 = require('./static_dependencies/noble-curves/secp256k1.js');
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* @class woofipro
|
|
16
|
+
* @augments Exchange
|
|
17
|
+
*/
|
|
18
|
+
class woofipro extends woofipro$1 {
|
|
19
|
+
describe() {
|
|
20
|
+
return this.deepExtend(super.describe(), {
|
|
21
|
+
'id': 'woofipro',
|
|
22
|
+
'name': 'WOOFI PRO',
|
|
23
|
+
'countries': ['KY'],
|
|
24
|
+
'rateLimit': 100,
|
|
25
|
+
'version': 'v1',
|
|
26
|
+
'certified': true,
|
|
27
|
+
'pro': true,
|
|
28
|
+
'hostname': 'dex.woo.org',
|
|
29
|
+
'has': {
|
|
30
|
+
'CORS': undefined,
|
|
31
|
+
'spot': false,
|
|
32
|
+
'margin': false,
|
|
33
|
+
'swap': true,
|
|
34
|
+
'future': false,
|
|
35
|
+
'option': false,
|
|
36
|
+
'addMargin': false,
|
|
37
|
+
'cancelAllOrders': true,
|
|
38
|
+
'cancelOrder': true,
|
|
39
|
+
'cancelOrders': true,
|
|
40
|
+
'cancelWithdraw': false,
|
|
41
|
+
'closeAllPositions': false,
|
|
42
|
+
'closePosition': false,
|
|
43
|
+
'createConvertTrade': false,
|
|
44
|
+
'createDepositAddress': false,
|
|
45
|
+
'createMarketBuyOrderWithCost': false,
|
|
46
|
+
'createMarketOrder': false,
|
|
47
|
+
'createMarketOrderWithCost': false,
|
|
48
|
+
'createMarketSellOrderWithCost': false,
|
|
49
|
+
'createOrder': true,
|
|
50
|
+
'createOrderWithTakeProfitAndStopLoss': true,
|
|
51
|
+
'createReduceOnlyOrder': true,
|
|
52
|
+
'createStopLimitOrder': false,
|
|
53
|
+
'createStopLossOrder': true,
|
|
54
|
+
'createStopMarketOrder': false,
|
|
55
|
+
'createStopOrder': false,
|
|
56
|
+
'createTakeProfitOrder': true,
|
|
57
|
+
'createTrailingAmountOrder': false,
|
|
58
|
+
'createTrailingPercentOrder': false,
|
|
59
|
+
'createTriggerOrder': true,
|
|
60
|
+
'fetchAccounts': false,
|
|
61
|
+
'fetchBalance': true,
|
|
62
|
+
'fetchCanceledOrders': false,
|
|
63
|
+
'fetchClosedOrder': false,
|
|
64
|
+
'fetchClosedOrders': true,
|
|
65
|
+
'fetchConvertCurrencies': false,
|
|
66
|
+
'fetchConvertQuote': false,
|
|
67
|
+
'fetchCurrencies': true,
|
|
68
|
+
'fetchDepositAddress': false,
|
|
69
|
+
'fetchDeposits': true,
|
|
70
|
+
'fetchDepositsWithdrawals': true,
|
|
71
|
+
'fetchFundingHistory': true,
|
|
72
|
+
'fetchFundingRate': true,
|
|
73
|
+
'fetchFundingRateHistory': true,
|
|
74
|
+
'fetchFundingRates': true,
|
|
75
|
+
'fetchIndexOHLCV': false,
|
|
76
|
+
'fetchLedger': true,
|
|
77
|
+
'fetchLeverage': true,
|
|
78
|
+
'fetchMarginAdjustmentHistory': false,
|
|
79
|
+
'fetchMarginMode': false,
|
|
80
|
+
'fetchMarkets': true,
|
|
81
|
+
'fetchMarkOHLCV': false,
|
|
82
|
+
'fetchMyTrades': true,
|
|
83
|
+
'fetchOHLCV': true,
|
|
84
|
+
'fetchOpenInterestHistory': false,
|
|
85
|
+
'fetchOpenOrder': false,
|
|
86
|
+
'fetchOpenOrders': true,
|
|
87
|
+
'fetchOrder': true,
|
|
88
|
+
'fetchOrderBook': true,
|
|
89
|
+
'fetchOrders': true,
|
|
90
|
+
'fetchOrderTrades': true,
|
|
91
|
+
'fetchPosition': true,
|
|
92
|
+
'fetchPositionMode': false,
|
|
93
|
+
'fetchPositions': true,
|
|
94
|
+
'fetchPremiumIndexOHLCV': false,
|
|
95
|
+
'fetchStatus': true,
|
|
96
|
+
'fetchTicker': false,
|
|
97
|
+
'fetchTickers': false,
|
|
98
|
+
'fetchTime': true,
|
|
99
|
+
'fetchTrades': true,
|
|
100
|
+
'fetchTradingFee': false,
|
|
101
|
+
'fetchTradingFees': true,
|
|
102
|
+
'fetchTransactions': 'emulated',
|
|
103
|
+
'fetchTransfers': false,
|
|
104
|
+
'fetchWithdrawals': true,
|
|
105
|
+
'reduceMargin': false,
|
|
106
|
+
'setLeverage': true,
|
|
107
|
+
'setMargin': false,
|
|
108
|
+
'setPositionMode': false,
|
|
109
|
+
'transfer': false,
|
|
110
|
+
'withdraw': true, // exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#token-withdraw
|
|
111
|
+
},
|
|
112
|
+
'timeframes': {
|
|
113
|
+
'1m': '1m',
|
|
114
|
+
'5m': '5m',
|
|
115
|
+
'15m': '15m',
|
|
116
|
+
'30m': '30m',
|
|
117
|
+
'1h': '1h',
|
|
118
|
+
'4h': '4h',
|
|
119
|
+
'12h': '12h',
|
|
120
|
+
'1d': '1d',
|
|
121
|
+
'1w': '1w',
|
|
122
|
+
'1M': '1mon',
|
|
123
|
+
'1y': '1y',
|
|
124
|
+
},
|
|
125
|
+
'urls': {
|
|
126
|
+
'logo': 'https://github.com/ccxt/ccxt/assets/43336371/b1e7b348-a0fc-4605-8b7f-91176958fd69',
|
|
127
|
+
'api': {
|
|
128
|
+
'public': 'https://api-evm.orderly.org',
|
|
129
|
+
'private': 'https://api-evm.orderly.org',
|
|
130
|
+
},
|
|
131
|
+
'test': {
|
|
132
|
+
'public': 'https://testnet-api-evm.orderly.org',
|
|
133
|
+
'private': 'https://testnet-api-evm.orderly.org',
|
|
134
|
+
},
|
|
135
|
+
'www': 'https://dex.woo.org',
|
|
136
|
+
'doc': [
|
|
137
|
+
'https://orderly.network/docs/build-on-evm/building-on-evm',
|
|
138
|
+
],
|
|
139
|
+
'fees': [
|
|
140
|
+
'https://dex.woo.org/en/orderly',
|
|
141
|
+
],
|
|
142
|
+
'referral': {
|
|
143
|
+
'url': 'https://dex.woo.org/en/trade?ref=CCXT',
|
|
144
|
+
'discount': 0.05,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
'api': {
|
|
148
|
+
'v1': {
|
|
149
|
+
'public': {
|
|
150
|
+
'get': {
|
|
151
|
+
'public/volume/stats': 1,
|
|
152
|
+
'public/broker/name': 1,
|
|
153
|
+
'public/chain_info/{broker_id}': 1,
|
|
154
|
+
'public/system_info': 1,
|
|
155
|
+
'public/vault_balance': 1,
|
|
156
|
+
'public/insurancefund': 1,
|
|
157
|
+
'public/chain_info': 1,
|
|
158
|
+
'faucet/usdc': 1,
|
|
159
|
+
'public/account': 1,
|
|
160
|
+
'get_account': 1,
|
|
161
|
+
'registration_nonce': 1,
|
|
162
|
+
'get_orderly_key': 1,
|
|
163
|
+
'public/liquidation': 1,
|
|
164
|
+
'public/liquidated_positions': 1,
|
|
165
|
+
'public/config': 1,
|
|
166
|
+
'public/campaign/ranking': 10,
|
|
167
|
+
'public/campaign/stats': 10,
|
|
168
|
+
'public/campaign/user': 10,
|
|
169
|
+
'public/campaign/stats/details': 10,
|
|
170
|
+
'public/campaigns': 10,
|
|
171
|
+
'public/points/leaderboard': 1,
|
|
172
|
+
'client/points': 1,
|
|
173
|
+
'public/points/epoch': 1,
|
|
174
|
+
'public/points/epoch_dates': 1,
|
|
175
|
+
'public/referral/check_ref_code': 1,
|
|
176
|
+
'public/referral/verify_ref_code': 1,
|
|
177
|
+
'referral/admin_info': 1,
|
|
178
|
+
'referral/info': 1,
|
|
179
|
+
'referral/referee_info': 1,
|
|
180
|
+
'referral/referee_rebate_summary': 1,
|
|
181
|
+
'referral/referee_history': 1,
|
|
182
|
+
'referral/referral_history': 1,
|
|
183
|
+
'referral/rebate_summary': 1,
|
|
184
|
+
'client/distribution_history': 1,
|
|
185
|
+
'tv/config': 1,
|
|
186
|
+
'tv/history': 1,
|
|
187
|
+
'tv/symbol_info': 1,
|
|
188
|
+
'public/funding_rate_history': 1,
|
|
189
|
+
'public/funding_rate/{symbol}': 0.33,
|
|
190
|
+
'public/funding_rates': 1,
|
|
191
|
+
'public/info': 1,
|
|
192
|
+
'public/info/{symbol}': 1,
|
|
193
|
+
'public/market_trades': 1,
|
|
194
|
+
'public/token': 1,
|
|
195
|
+
'public/futures': 1,
|
|
196
|
+
'public/futures/{symbol}': 1,
|
|
197
|
+
},
|
|
198
|
+
'post': {
|
|
199
|
+
'register_account': 1,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
'private': {
|
|
203
|
+
'get': {
|
|
204
|
+
'client/key_info': 6,
|
|
205
|
+
'client/orderly_key_ip_restriction': 6,
|
|
206
|
+
'order/{oid}': 1,
|
|
207
|
+
'client/order/{client_order_id}': 1,
|
|
208
|
+
'algo/order/{oid}': 1,
|
|
209
|
+
'algo/client/order/{client_order_id}': 1,
|
|
210
|
+
'orders': 1,
|
|
211
|
+
'algo/orders': 1,
|
|
212
|
+
'trade/{tid}': 1,
|
|
213
|
+
'trades': 1,
|
|
214
|
+
'order/{oid}/trades': 1,
|
|
215
|
+
'client/liquidator_liquidations': 1,
|
|
216
|
+
'liquidations': 1,
|
|
217
|
+
'asset/history': 60,
|
|
218
|
+
'client/holding': 1,
|
|
219
|
+
'withdraw_nonce': 1,
|
|
220
|
+
'settle_nonce': 1,
|
|
221
|
+
'pnl_settlement/history': 1,
|
|
222
|
+
'volume/user/daily': 60,
|
|
223
|
+
'volume/user/stats': 60,
|
|
224
|
+
'client/statistics': 60,
|
|
225
|
+
'client/info': 60,
|
|
226
|
+
'client/statistics/daily': 60,
|
|
227
|
+
'positions': 3.33,
|
|
228
|
+
'position/{symbol}': 3.33,
|
|
229
|
+
'funding_fee/history': 30,
|
|
230
|
+
'notification/inbox/notifications': 60,
|
|
231
|
+
'notification/inbox/unread': 60,
|
|
232
|
+
'volume/broker/daily': 60,
|
|
233
|
+
'broker/fee_rate/default': 10,
|
|
234
|
+
'broker/user_info': 10,
|
|
235
|
+
'orderbook/{symbol}': 1,
|
|
236
|
+
'kline': 1,
|
|
237
|
+
},
|
|
238
|
+
'post': {
|
|
239
|
+
'orderly_key': 1,
|
|
240
|
+
'client/set_orderly_key_ip_restriction': 6,
|
|
241
|
+
'client/reset_orderly_key_ip_restriction': 6,
|
|
242
|
+
'order': 1,
|
|
243
|
+
'batch-order': 10,
|
|
244
|
+
'algo/order': 1,
|
|
245
|
+
'liquidation': 1,
|
|
246
|
+
'claim_insurance_fund': 1,
|
|
247
|
+
'withdraw_request': 1,
|
|
248
|
+
'settle_pnl': 1,
|
|
249
|
+
'notification/inbox/mark_read': 60,
|
|
250
|
+
'notification/inbox/mark_read_all': 60,
|
|
251
|
+
'client/leverage': 120,
|
|
252
|
+
'client/maintenance_config': 60,
|
|
253
|
+
'delegate_signer': 10,
|
|
254
|
+
'delegate_orderly_key': 10,
|
|
255
|
+
'delegate_settle_pnl': 10,
|
|
256
|
+
'delegate_withdraw_request': 10,
|
|
257
|
+
'broker/fee_rate/set': 10,
|
|
258
|
+
'broker/fee_rate/set_default': 10,
|
|
259
|
+
'broker/fee_rate/default': 10,
|
|
260
|
+
'referral/create': 10,
|
|
261
|
+
'referral/update': 10,
|
|
262
|
+
'referral/bind': 10,
|
|
263
|
+
'referral/edit_split': 10,
|
|
264
|
+
},
|
|
265
|
+
'put': {
|
|
266
|
+
'order': 1,
|
|
267
|
+
'algo/order': 1,
|
|
268
|
+
},
|
|
269
|
+
'delete': {
|
|
270
|
+
'order': 1,
|
|
271
|
+
'algo/order': 1,
|
|
272
|
+
'client/order': 1,
|
|
273
|
+
'algo/client/order': 1,
|
|
274
|
+
'algo/orders': 1,
|
|
275
|
+
'orders': 1,
|
|
276
|
+
'batch-order': 1,
|
|
277
|
+
'client/batch-order': 1,
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
'requiredCredentials': {
|
|
283
|
+
'apiKey': true,
|
|
284
|
+
'secret': true,
|
|
285
|
+
'accountId': true,
|
|
286
|
+
'privateKey': false,
|
|
287
|
+
},
|
|
288
|
+
'fees': {
|
|
289
|
+
'trading': {
|
|
290
|
+
'tierBased': true,
|
|
291
|
+
'percentage': true,
|
|
292
|
+
'maker': this.parseNumber('0.0002'),
|
|
293
|
+
'taker': this.parseNumber('0.0005'),
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
'options': {
|
|
297
|
+
'sandboxMode': false,
|
|
298
|
+
'brokerId': 'CCXT',
|
|
299
|
+
'verifyingContractAddress': '0x6F7a338F2aA472838dEFD3283eB360d4Dff5D203',
|
|
300
|
+
},
|
|
301
|
+
'commonCurrencies': {},
|
|
302
|
+
'exceptions': {
|
|
303
|
+
'exact': {
|
|
304
|
+
'-1000': errors.ExchangeError,
|
|
305
|
+
'-1001': errors.AuthenticationError,
|
|
306
|
+
'-1002': errors.AuthenticationError,
|
|
307
|
+
'-1003': errors.RateLimitExceeded,
|
|
308
|
+
'-1004': errors.BadRequest,
|
|
309
|
+
'-1005': errors.BadRequest,
|
|
310
|
+
'-1006': errors.InvalidOrder,
|
|
311
|
+
'-1007': errors.BadRequest,
|
|
312
|
+
'-1008': errors.InvalidOrder,
|
|
313
|
+
'-1009': errors.InsufficientFunds,
|
|
314
|
+
'-1011': errors.NetworkError,
|
|
315
|
+
'-1012': errors.BadRequest,
|
|
316
|
+
'-1101': errors.InsufficientFunds,
|
|
317
|
+
'-1102': errors.InvalidOrder,
|
|
318
|
+
'-1103': errors.InvalidOrder,
|
|
319
|
+
'-1104': errors.InvalidOrder,
|
|
320
|
+
'-1105': errors.InvalidOrder,
|
|
321
|
+
'-1201': errors.BadRequest,
|
|
322
|
+
'-1202': errors.BadRequest,
|
|
323
|
+
'29': errors.BadRequest,
|
|
324
|
+
'9': errors.AuthenticationError,
|
|
325
|
+
'3': errors.AuthenticationError,
|
|
326
|
+
'2': errors.BadRequest,
|
|
327
|
+
'15': errors.BadRequest, // {"success":false,"code":15,"message":"BrokerId is not exist"}
|
|
328
|
+
},
|
|
329
|
+
'broad': {},
|
|
330
|
+
},
|
|
331
|
+
'precisionMode': number.TICK_SIZE,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
setSandboxMode(enable) {
|
|
335
|
+
super.setSandboxMode(enable);
|
|
336
|
+
this.options['sandboxMode'] = enable;
|
|
337
|
+
}
|
|
338
|
+
async fetchStatus(params = {}) {
|
|
339
|
+
/**
|
|
340
|
+
* @method
|
|
341
|
+
* @name woofipro#fetchStatus
|
|
342
|
+
* @description the latest known information on the availability of the exchange API
|
|
343
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-system-maintenance-status
|
|
344
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
345
|
+
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
|
346
|
+
*/
|
|
347
|
+
const response = await this.v1PublicGetPublicSystemInfo(params);
|
|
348
|
+
//
|
|
349
|
+
// {
|
|
350
|
+
// "success": true,
|
|
351
|
+
// "data": {
|
|
352
|
+
// "status": 0,
|
|
353
|
+
// "msg": "System is functioning properly."
|
|
354
|
+
// },
|
|
355
|
+
// "timestamp": "1709274106602"
|
|
356
|
+
// }
|
|
357
|
+
//
|
|
358
|
+
const data = this.safeDict(response, 'data', {});
|
|
359
|
+
let status = this.safeString(data, 'status');
|
|
360
|
+
if (status === undefined) {
|
|
361
|
+
status = 'error';
|
|
362
|
+
}
|
|
363
|
+
else if (status === '0') {
|
|
364
|
+
status = 'ok';
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
status = 'maintenance';
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
'status': status,
|
|
371
|
+
'updated': undefined,
|
|
372
|
+
'eta': undefined,
|
|
373
|
+
'url': undefined,
|
|
374
|
+
'info': response,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
async fetchTime(params = {}) {
|
|
378
|
+
/**
|
|
379
|
+
* @method
|
|
380
|
+
* @name woofipro#fetchTime
|
|
381
|
+
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
382
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-system-maintenance-status
|
|
383
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
384
|
+
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
385
|
+
*/
|
|
386
|
+
const response = await this.v1PublicGetPublicSystemInfo(params);
|
|
387
|
+
//
|
|
388
|
+
// {
|
|
389
|
+
// "success": true,
|
|
390
|
+
// "data": {
|
|
391
|
+
// "status": 0,
|
|
392
|
+
// "msg": "System is functioning properly."
|
|
393
|
+
// },
|
|
394
|
+
// "timestamp": "1709274106602"
|
|
395
|
+
// }
|
|
396
|
+
//
|
|
397
|
+
return this.safeInteger(response, 'timestamp');
|
|
398
|
+
}
|
|
399
|
+
parseMarket(market) {
|
|
400
|
+
//
|
|
401
|
+
// {
|
|
402
|
+
// "symbol": "PERP_BTC_USDC",
|
|
403
|
+
// "quote_min": 123,
|
|
404
|
+
// "quote_max": 100000,
|
|
405
|
+
// "quote_tick": 0.1,
|
|
406
|
+
// "base_min": 0.00001,
|
|
407
|
+
// "base_max": 20,
|
|
408
|
+
// "base_tick": 0.00001,
|
|
409
|
+
// "min_notional": 1,
|
|
410
|
+
// "price_range": 0.02,
|
|
411
|
+
// "price_scope": 0.4,
|
|
412
|
+
// "std_liquidation_fee": 0.03,
|
|
413
|
+
// "liquidator_fee": 0.015,
|
|
414
|
+
// "claim_insurance_fund_discount": 0.0075,
|
|
415
|
+
// "funding_period": 8,
|
|
416
|
+
// "cap_funding": 0.000375,
|
|
417
|
+
// "floor_funding": -0.000375,
|
|
418
|
+
// "interest_rate": 0.0001,
|
|
419
|
+
// "created_time": 1684140107326,
|
|
420
|
+
// "updated_time": 1685345968053,
|
|
421
|
+
// "base_mmr": 0.05,
|
|
422
|
+
// "base_imr": 0.1,
|
|
423
|
+
// "imr_factor": 0.0002512,
|
|
424
|
+
// "liquidation_tier": "1"
|
|
425
|
+
// }
|
|
426
|
+
//
|
|
427
|
+
const marketId = this.safeString(market, 'symbol');
|
|
428
|
+
const parts = marketId.split('_');
|
|
429
|
+
const marketType = 'swap';
|
|
430
|
+
const baseId = this.safeString(parts, 1);
|
|
431
|
+
const quoteId = this.safeString(parts, 2);
|
|
432
|
+
const base = this.safeCurrencyCode(baseId);
|
|
433
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
434
|
+
const settleId = this.safeString(parts, 2);
|
|
435
|
+
const settle = this.safeCurrencyCode(settleId);
|
|
436
|
+
const symbol = base + '/' + quote + ':' + settle;
|
|
437
|
+
return {
|
|
438
|
+
'id': marketId,
|
|
439
|
+
'symbol': symbol,
|
|
440
|
+
'base': base,
|
|
441
|
+
'quote': quote,
|
|
442
|
+
'settle': settle,
|
|
443
|
+
'baseId': baseId,
|
|
444
|
+
'quoteId': quoteId,
|
|
445
|
+
'settleId': settleId,
|
|
446
|
+
'type': marketType,
|
|
447
|
+
'spot': false,
|
|
448
|
+
'margin': false,
|
|
449
|
+
'swap': true,
|
|
450
|
+
'future': false,
|
|
451
|
+
'option': false,
|
|
452
|
+
'active': undefined,
|
|
453
|
+
'contract': true,
|
|
454
|
+
'linear': true,
|
|
455
|
+
'inverse': undefined,
|
|
456
|
+
'contractSize': this.parseNumber('1'),
|
|
457
|
+
'expiry': undefined,
|
|
458
|
+
'expiryDatetime': undefined,
|
|
459
|
+
'strike': undefined,
|
|
460
|
+
'optionType': undefined,
|
|
461
|
+
'precision': {
|
|
462
|
+
'amount': this.safeNumber(market, 'base_tick'),
|
|
463
|
+
'price': this.safeNumber(market, 'quote_tick'),
|
|
464
|
+
},
|
|
465
|
+
'limits': {
|
|
466
|
+
'leverage': {
|
|
467
|
+
'min': undefined,
|
|
468
|
+
'max': undefined,
|
|
469
|
+
},
|
|
470
|
+
'amount': {
|
|
471
|
+
'min': this.safeNumber(market, 'base_min'),
|
|
472
|
+
'max': this.safeNumber(market, 'base_max'),
|
|
473
|
+
},
|
|
474
|
+
'price': {
|
|
475
|
+
'min': this.safeNumber(market, 'quote_min'),
|
|
476
|
+
'max': this.safeNumber(market, 'quote_max'),
|
|
477
|
+
},
|
|
478
|
+
'cost': {
|
|
479
|
+
'min': this.safeNumber(market, 'min_notional'),
|
|
480
|
+
'max': undefined,
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
'created': this.safeInteger(market, 'created_time'),
|
|
484
|
+
'info': market,
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
async fetchMarkets(params = {}) {
|
|
488
|
+
/**
|
|
489
|
+
* @method
|
|
490
|
+
* @name woofipro#fetchMarkets
|
|
491
|
+
* @description retrieves data on all markets for woofipro
|
|
492
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-available-symbols
|
|
493
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
494
|
+
* @returns {object[]} an array of objects representing market data
|
|
495
|
+
*/
|
|
496
|
+
const response = await this.v1PublicGetPublicInfo(params);
|
|
497
|
+
//
|
|
498
|
+
// {
|
|
499
|
+
// "success": true,
|
|
500
|
+
// "timestamp": 1702989203989,
|
|
501
|
+
// "data": {
|
|
502
|
+
// "rows": [
|
|
503
|
+
// {
|
|
504
|
+
// "symbol": "PERP_BTC_USDC",
|
|
505
|
+
// "quote_min": 123,
|
|
506
|
+
// "quote_max": 100000,
|
|
507
|
+
// "quote_tick": 0.1,
|
|
508
|
+
// "base_min": 0.00001,
|
|
509
|
+
// "base_max": 20,
|
|
510
|
+
// "base_tick": 0.00001,
|
|
511
|
+
// "min_notional": 1,
|
|
512
|
+
// "price_range": 0.02,
|
|
513
|
+
// "price_scope": 0.4,
|
|
514
|
+
// "std_liquidation_fee": 0.03,
|
|
515
|
+
// "liquidator_fee": 0.015,
|
|
516
|
+
// "claim_insurance_fund_discount": 0.0075,
|
|
517
|
+
// "funding_period": 8,
|
|
518
|
+
// "cap_funding": 0.000375,
|
|
519
|
+
// "floor_funding": -0.000375,
|
|
520
|
+
// "interest_rate": 0.0001,
|
|
521
|
+
// "created_time": 1684140107326,
|
|
522
|
+
// "updated_time": 1685345968053,
|
|
523
|
+
// "base_mmr": 0.05,
|
|
524
|
+
// "base_imr": 0.1,
|
|
525
|
+
// "imr_factor": 0.0002512,
|
|
526
|
+
// "liquidation_tier": "1"
|
|
527
|
+
// }
|
|
528
|
+
// ]
|
|
529
|
+
// }
|
|
530
|
+
// }
|
|
531
|
+
//
|
|
532
|
+
const data = this.safeDict(response, 'data', {});
|
|
533
|
+
const rows = this.safeList(data, 'rows', []);
|
|
534
|
+
return this.parseMarkets(rows);
|
|
535
|
+
}
|
|
536
|
+
async fetchCurrencies(params = {}) {
|
|
537
|
+
/**
|
|
538
|
+
* @method
|
|
539
|
+
* @name woofipro#fetchCurrencies
|
|
540
|
+
* @description fetches all available currencies on an exchange
|
|
541
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-token-info
|
|
542
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
543
|
+
* @returns {object} an associative dictionary of currencies
|
|
544
|
+
*/
|
|
545
|
+
const result = {};
|
|
546
|
+
const response = await this.v1PublicGetPublicToken(params);
|
|
547
|
+
//
|
|
548
|
+
// {
|
|
549
|
+
// "success": true,
|
|
550
|
+
// "timestamp": 1702989203989,
|
|
551
|
+
// "data": {
|
|
552
|
+
// "rows": [{
|
|
553
|
+
// "token": "USDC",
|
|
554
|
+
// "decimals": 6,
|
|
555
|
+
// "minimum_withdraw_amount": 0.000001,
|
|
556
|
+
// "token_hash": "0xd6aca1be9729c13d677335161321649cccae6a591554772516700f986f942eaa",
|
|
557
|
+
// "chain_details": [{
|
|
558
|
+
// "chain_id": 43113,
|
|
559
|
+
// "contract_address": "0x5d64c9cfb0197775b4b3ad9be4d3c7976e0d8dc3",
|
|
560
|
+
// "cross_chain_withdrawal_fee": 123,
|
|
561
|
+
// "decimals": 6,
|
|
562
|
+
// "withdraw_fee": 2
|
|
563
|
+
// }]
|
|
564
|
+
// }
|
|
565
|
+
// ]
|
|
566
|
+
// }
|
|
567
|
+
// }
|
|
568
|
+
//
|
|
569
|
+
const data = this.safeDict(response, 'data', {});
|
|
570
|
+
const tokenRows = this.safeList(data, 'rows', []);
|
|
571
|
+
for (let i = 0; i < tokenRows.length; i++) {
|
|
572
|
+
const token = tokenRows[i];
|
|
573
|
+
const currencyId = this.safeString(token, 'token');
|
|
574
|
+
const networks = this.safeList(token, 'chain_details');
|
|
575
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
576
|
+
let minPrecision = undefined;
|
|
577
|
+
const resultingNetworks = {};
|
|
578
|
+
for (let j = 0; j < networks.length; j++) {
|
|
579
|
+
const network = networks[j];
|
|
580
|
+
// TODO: transform chain id to human readable name
|
|
581
|
+
const networkId = this.safeString(network, 'chain_id');
|
|
582
|
+
const precision = this.parsePrecision(this.safeString(network, 'decimals'));
|
|
583
|
+
if (precision !== undefined) {
|
|
584
|
+
minPrecision = (minPrecision === undefined) ? precision : Precise["default"].stringMin(precision, minPrecision);
|
|
585
|
+
}
|
|
586
|
+
resultingNetworks[networkId] = {
|
|
587
|
+
'id': networkId,
|
|
588
|
+
'network': networkId,
|
|
589
|
+
'limits': {
|
|
590
|
+
'withdraw': {
|
|
591
|
+
'min': undefined,
|
|
592
|
+
'max': undefined,
|
|
593
|
+
},
|
|
594
|
+
'deposit': {
|
|
595
|
+
'min': undefined,
|
|
596
|
+
'max': undefined,
|
|
597
|
+
},
|
|
598
|
+
},
|
|
599
|
+
'active': undefined,
|
|
600
|
+
'deposit': undefined,
|
|
601
|
+
'withdraw': undefined,
|
|
602
|
+
'fee': this.safeNumber(network, 'withdrawal_fee'),
|
|
603
|
+
'precision': this.parseNumber(precision),
|
|
604
|
+
'info': network,
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
result[code] = {
|
|
608
|
+
'id': currencyId,
|
|
609
|
+
'name': currencyId,
|
|
610
|
+
'code': code,
|
|
611
|
+
'precision': this.parseNumber(minPrecision),
|
|
612
|
+
'active': undefined,
|
|
613
|
+
'fee': undefined,
|
|
614
|
+
'networks': resultingNetworks,
|
|
615
|
+
'deposit': undefined,
|
|
616
|
+
'withdraw': undefined,
|
|
617
|
+
'limits': {
|
|
618
|
+
'deposit': {
|
|
619
|
+
'min': undefined,
|
|
620
|
+
'max': undefined,
|
|
621
|
+
},
|
|
622
|
+
'withdraw': {
|
|
623
|
+
'min': this.safeNumber(token, 'minimum_withdraw_amount'),
|
|
624
|
+
'max': undefined,
|
|
625
|
+
},
|
|
626
|
+
},
|
|
627
|
+
'info': token,
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
return result;
|
|
631
|
+
}
|
|
632
|
+
parseTokenAndFeeTemp(item, feeTokenKey, feeAmountKey) {
|
|
633
|
+
const feeCost = this.safeString(item, feeAmountKey);
|
|
634
|
+
let fee = undefined;
|
|
635
|
+
if (feeCost !== undefined) {
|
|
636
|
+
const feeCurrencyId = this.safeString(item, feeTokenKey);
|
|
637
|
+
const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
|
|
638
|
+
fee = {
|
|
639
|
+
'cost': feeCost,
|
|
640
|
+
'currency': feeCurrencyCode,
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
return fee;
|
|
644
|
+
}
|
|
645
|
+
parseTrade(trade, market = undefined) {
|
|
646
|
+
//
|
|
647
|
+
// public/market_trades
|
|
648
|
+
//
|
|
649
|
+
// {
|
|
650
|
+
// "symbol": "SPOT_BTC_USDT",
|
|
651
|
+
// "side": "SELL",
|
|
652
|
+
// "executed_price": 46222.35,
|
|
653
|
+
// "executed_quantity": 0.0012,
|
|
654
|
+
// "executed_timestamp": "1683878609166"
|
|
655
|
+
// }
|
|
656
|
+
//
|
|
657
|
+
// fetchOrderTrades, fetchOrder
|
|
658
|
+
//
|
|
659
|
+
// {
|
|
660
|
+
// "id": "99119876",
|
|
661
|
+
// "symbol": "SPOT_WOO_USDT",
|
|
662
|
+
// "fee": "0.0024",
|
|
663
|
+
// "side": "BUY",
|
|
664
|
+
// "executed_timestamp": "1641481113084",
|
|
665
|
+
// "order_id": "87001234",
|
|
666
|
+
// "order_tag": "default", <-- this param only in "fetchOrderTrades"
|
|
667
|
+
// "executed_price": "1",
|
|
668
|
+
// "executed_quantity": "12",
|
|
669
|
+
// "fee_asset": "WOO",
|
|
670
|
+
// "is_maker": "1"
|
|
671
|
+
// }
|
|
672
|
+
//
|
|
673
|
+
const isFromFetchOrder = ('id' in trade);
|
|
674
|
+
const timestamp = this.safeInteger(trade, 'executed_timestamp');
|
|
675
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
676
|
+
market = this.safeMarket(marketId, market);
|
|
677
|
+
const symbol = market['symbol'];
|
|
678
|
+
const price = this.safeString(trade, 'executed_price');
|
|
679
|
+
const amount = this.safeString(trade, 'executed_quantity');
|
|
680
|
+
const order_id = this.safeString(trade, 'order_id');
|
|
681
|
+
const fee = this.parseTokenAndFeeTemp(trade, 'fee_asset', 'fee');
|
|
682
|
+
const cost = Precise["default"].stringMul(price, amount);
|
|
683
|
+
const side = this.safeStringLower(trade, 'side');
|
|
684
|
+
const id = this.safeString(trade, 'id');
|
|
685
|
+
let takerOrMaker = undefined;
|
|
686
|
+
if (isFromFetchOrder) {
|
|
687
|
+
const isMaker = this.safeString(trade, 'is_maker') === '1';
|
|
688
|
+
takerOrMaker = isMaker ? 'maker' : 'taker';
|
|
689
|
+
}
|
|
690
|
+
return this.safeTrade({
|
|
691
|
+
'id': id,
|
|
692
|
+
'timestamp': timestamp,
|
|
693
|
+
'datetime': this.iso8601(timestamp),
|
|
694
|
+
'symbol': symbol,
|
|
695
|
+
'side': side,
|
|
696
|
+
'price': price,
|
|
697
|
+
'amount': amount,
|
|
698
|
+
'cost': cost,
|
|
699
|
+
'order': order_id,
|
|
700
|
+
'takerOrMaker': takerOrMaker,
|
|
701
|
+
'type': undefined,
|
|
702
|
+
'fee': fee,
|
|
703
|
+
'info': trade,
|
|
704
|
+
}, market);
|
|
705
|
+
}
|
|
706
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
707
|
+
/**
|
|
708
|
+
* @method
|
|
709
|
+
* @name woofipro#fetchTrades
|
|
710
|
+
* @description get the list of most recent trades for a particular symbol
|
|
711
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-market-trades
|
|
712
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
713
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
714
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
715
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
716
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
717
|
+
*/
|
|
718
|
+
await this.loadMarkets();
|
|
719
|
+
const market = this.market(symbol);
|
|
720
|
+
const request = {
|
|
721
|
+
'symbol': market['id'],
|
|
722
|
+
};
|
|
723
|
+
if (limit !== undefined) {
|
|
724
|
+
request['limit'] = limit;
|
|
725
|
+
}
|
|
726
|
+
const response = await this.v1PublicGetPublicMarketTrades(this.extend(request, params));
|
|
727
|
+
//
|
|
728
|
+
// {
|
|
729
|
+
// "success": true,
|
|
730
|
+
// "timestamp": 1702989203989,
|
|
731
|
+
// "data": {
|
|
732
|
+
// "rows": [{
|
|
733
|
+
// "symbol": "PERP_ETH_USDC",
|
|
734
|
+
// "side": "BUY",
|
|
735
|
+
// "executed_price": 2050,
|
|
736
|
+
// "executed_quantity": 1,
|
|
737
|
+
// "executed_timestamp": 1683878609166
|
|
738
|
+
// }]
|
|
739
|
+
// }
|
|
740
|
+
// }
|
|
741
|
+
//
|
|
742
|
+
const data = this.safeDict(response, 'data', {});
|
|
743
|
+
const rows = this.safeList(data, 'rows', []);
|
|
744
|
+
return this.parseTrades(rows, market, since, limit);
|
|
745
|
+
}
|
|
746
|
+
parseFundingRate(fundingRate, market = undefined) {
|
|
747
|
+
//
|
|
748
|
+
// {
|
|
749
|
+
// "symbol":"PERP_AAVE_USDT",
|
|
750
|
+
// "est_funding_rate":-0.00003447,
|
|
751
|
+
// "est_funding_rate_timestamp":1653633959001,
|
|
752
|
+
// "last_funding_rate":-0.00002094,
|
|
753
|
+
// "last_funding_rate_timestamp":1653631200000,
|
|
754
|
+
// "next_funding_time":1653634800000,
|
|
755
|
+
// "sum_unitary_funding": 521.367
|
|
756
|
+
// }
|
|
757
|
+
//
|
|
758
|
+
//
|
|
759
|
+
const symbol = this.safeString(fundingRate, 'symbol');
|
|
760
|
+
market = this.market(symbol);
|
|
761
|
+
const nextFundingTimestamp = this.safeInteger(fundingRate, 'next_funding_time');
|
|
762
|
+
const estFundingRateTimestamp = this.safeInteger(fundingRate, 'est_funding_rate_timestamp');
|
|
763
|
+
const lastFundingRateTimestamp = this.safeInteger(fundingRate, 'last_funding_rate_timestamp');
|
|
764
|
+
return {
|
|
765
|
+
'info': fundingRate,
|
|
766
|
+
'symbol': market['symbol'],
|
|
767
|
+
'markPrice': undefined,
|
|
768
|
+
'indexPrice': undefined,
|
|
769
|
+
'interestRate': this.parseNumber('0'),
|
|
770
|
+
'estimatedSettlePrice': undefined,
|
|
771
|
+
'timestamp': estFundingRateTimestamp,
|
|
772
|
+
'datetime': this.iso8601(estFundingRateTimestamp),
|
|
773
|
+
'fundingRate': this.safeNumber(fundingRate, 'est_funding_rate'),
|
|
774
|
+
'fundingTimestamp': nextFundingTimestamp,
|
|
775
|
+
'fundingDatetime': this.iso8601(nextFundingTimestamp),
|
|
776
|
+
'nextFundingRate': undefined,
|
|
777
|
+
'nextFundingTimestamp': undefined,
|
|
778
|
+
'nextFundingDatetime': undefined,
|
|
779
|
+
'previousFundingRate': this.safeNumber(fundingRate, 'last_funding_rate'),
|
|
780
|
+
'previousFundingTimestamp': lastFundingRateTimestamp,
|
|
781
|
+
'previousFundingDatetime': this.iso8601(lastFundingRateTimestamp),
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
async fetchFundingRate(symbol, params = {}) {
|
|
785
|
+
/**
|
|
786
|
+
* @method
|
|
787
|
+
* @name woofipro#fetchFundingRate
|
|
788
|
+
* @description fetch the current funding rate
|
|
789
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-predicted-funding-rate-for-one-market
|
|
790
|
+
* @param {string} symbol unified market symbol
|
|
791
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
792
|
+
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
793
|
+
*/
|
|
794
|
+
await this.loadMarkets();
|
|
795
|
+
const market = this.market(symbol);
|
|
796
|
+
const request = {
|
|
797
|
+
'symbol': market['id'],
|
|
798
|
+
};
|
|
799
|
+
const response = await this.v1PublicGetPublicFundingRateSymbol(this.extend(request, params));
|
|
800
|
+
//
|
|
801
|
+
// {
|
|
802
|
+
// "success": true,
|
|
803
|
+
// "timestamp": 1702989203989,
|
|
804
|
+
// "data": {
|
|
805
|
+
// "symbol": "PERP_ETH_USDC",
|
|
806
|
+
// "est_funding_rate": 123,
|
|
807
|
+
// "est_funding_rate_timestamp": 1683880020000,
|
|
808
|
+
// "last_funding_rate": 0.0001,
|
|
809
|
+
// "last_funding_rate_timestamp": 1683878400000,
|
|
810
|
+
// "next_funding_time": 1683907200000,
|
|
811
|
+
// "sum_unitary_funding": 521.367
|
|
812
|
+
// }
|
|
813
|
+
// }
|
|
814
|
+
//
|
|
815
|
+
const data = this.safeDict(response, 'data', {});
|
|
816
|
+
return this.parseFundingRate(data, market);
|
|
817
|
+
}
|
|
818
|
+
async fetchFundingRates(symbols = undefined, params = {}) {
|
|
819
|
+
/**
|
|
820
|
+
* @method
|
|
821
|
+
* @name woofipro#fetchFundingRates
|
|
822
|
+
* @description fetch the current funding rates
|
|
823
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-predicted-funding-rates-for-all-markets
|
|
824
|
+
* @param {string[]} symbols unified market symbols
|
|
825
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
826
|
+
* @returns {object[]} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
|
|
827
|
+
*/
|
|
828
|
+
await this.loadMarkets();
|
|
829
|
+
symbols = this.marketSymbols(symbols);
|
|
830
|
+
const response = await this.v1PublicGetPublicFundingRates(params);
|
|
831
|
+
//
|
|
832
|
+
// {
|
|
833
|
+
// "success": true,
|
|
834
|
+
// "timestamp": 1702989203989,
|
|
835
|
+
// "data": {
|
|
836
|
+
// "rows": [{
|
|
837
|
+
// "symbol": "PERP_ETH_USDC",
|
|
838
|
+
// "est_funding_rate": 123,
|
|
839
|
+
// "est_funding_rate_timestamp": 1683880020000,
|
|
840
|
+
// "last_funding_rate": 0.0001,
|
|
841
|
+
// "last_funding_rate_timestamp": 1683878400000,
|
|
842
|
+
// "next_funding_time": 1683907200000,
|
|
843
|
+
// "sum_unitary_funding": 521.367
|
|
844
|
+
// }]
|
|
845
|
+
// }
|
|
846
|
+
// }
|
|
847
|
+
//
|
|
848
|
+
const data = this.safeDict(response, 'data', {});
|
|
849
|
+
const rows = this.safeList(data, 'rows', []);
|
|
850
|
+
const result = this.parseFundingRates(rows);
|
|
851
|
+
return this.filterByArray(result, 'symbol', symbols);
|
|
852
|
+
}
|
|
853
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
854
|
+
/**
|
|
855
|
+
* @method
|
|
856
|
+
* @name woofipro#fetchFundingRateHistory
|
|
857
|
+
* @description fetches historical funding rate prices
|
|
858
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-funding-rate-history-for-one-market
|
|
859
|
+
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
860
|
+
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
861
|
+
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
|
862
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
863
|
+
* @param {int} [params.until] timestamp in ms of the latest funding rate
|
|
864
|
+
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
865
|
+
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
|
866
|
+
*/
|
|
867
|
+
await this.loadMarkets();
|
|
868
|
+
let paginate = false;
|
|
869
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
|
|
870
|
+
if (paginate) {
|
|
871
|
+
return await this.fetchPaginatedCallIncremental('fetchFundingRateHistory', symbol, since, limit, params, 'page', 25);
|
|
872
|
+
}
|
|
873
|
+
let request = {};
|
|
874
|
+
if (symbol !== undefined) {
|
|
875
|
+
const market = this.market(symbol);
|
|
876
|
+
symbol = market['symbol'];
|
|
877
|
+
request['symbol'] = market['id'];
|
|
878
|
+
}
|
|
879
|
+
if (since !== undefined) {
|
|
880
|
+
request['start_t'] = since;
|
|
881
|
+
}
|
|
882
|
+
[request, params] = this.handleUntilOption('end_t', request, params, 0.001);
|
|
883
|
+
const response = await this.v1PublicGetPublicFundingRateHistory(this.extend(request, params));
|
|
884
|
+
//
|
|
885
|
+
// {
|
|
886
|
+
// "success": true,
|
|
887
|
+
// "timestamp": 1702989203989,
|
|
888
|
+
// "data": {
|
|
889
|
+
// "rows": [{
|
|
890
|
+
// "symbol": "PERP_ETH_USDC",
|
|
891
|
+
// "funding_rate": 0.0001,
|
|
892
|
+
// "funding_rate_timestamp": 1684224000000,
|
|
893
|
+
// "next_funding_time": 1684252800000
|
|
894
|
+
// }],
|
|
895
|
+
// "meta": {
|
|
896
|
+
// "total": 9,
|
|
897
|
+
// "records_per_page": 25,
|
|
898
|
+
// "current_page": 1
|
|
899
|
+
// }
|
|
900
|
+
// }
|
|
901
|
+
// }
|
|
902
|
+
//
|
|
903
|
+
const data = this.safeDict(response, 'data', {});
|
|
904
|
+
const result = this.safeList(data, 'rows', []);
|
|
905
|
+
const rates = [];
|
|
906
|
+
for (let i = 0; i < result.length; i++) {
|
|
907
|
+
const entry = result[i];
|
|
908
|
+
const marketId = this.safeString(entry, 'symbol');
|
|
909
|
+
const timestamp = this.safeInteger(entry, 'funding_rate_timestamp');
|
|
910
|
+
rates.push({
|
|
911
|
+
'info': entry,
|
|
912
|
+
'symbol': this.safeSymbol(marketId),
|
|
913
|
+
'fundingRate': this.safeNumber(entry, 'funding_rate'),
|
|
914
|
+
'timestamp': timestamp,
|
|
915
|
+
'datetime': this.iso8601(timestamp),
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
const sorted = this.sortBy(rates, 'timestamp');
|
|
919
|
+
return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
|
|
920
|
+
}
|
|
921
|
+
async fetchTradingFees(params = {}) {
|
|
922
|
+
/**
|
|
923
|
+
* @method
|
|
924
|
+
* @name woofipro#fetchTradingFees
|
|
925
|
+
* @description fetch the trading fees for multiple markets
|
|
926
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-account-information
|
|
927
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
928
|
+
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
929
|
+
*/
|
|
930
|
+
await this.loadMarkets();
|
|
931
|
+
const response = await this.v1PrivateGetClientInfo(params);
|
|
932
|
+
//
|
|
933
|
+
// {
|
|
934
|
+
// "success": true,
|
|
935
|
+
// "timestamp": 1702989203989,
|
|
936
|
+
// "data": {
|
|
937
|
+
// "account_id": "<string>",
|
|
938
|
+
// "email": "test@test.com",
|
|
939
|
+
// "account_mode": "FUTURES",
|
|
940
|
+
// "max_leverage": 20,
|
|
941
|
+
// "taker_fee_rate": 123,
|
|
942
|
+
// "maker_fee_rate": 123,
|
|
943
|
+
// "futures_taker_fee_rate": 123,
|
|
944
|
+
// "futures_maker_fee_rate": 123,
|
|
945
|
+
// "maintenance_cancel_orders": true,
|
|
946
|
+
// "imr_factor": {
|
|
947
|
+
// "PERP_BTC_USDC": 123,
|
|
948
|
+
// "PERP_ETH_USDC": 123,
|
|
949
|
+
// "PERP_NEAR_USDC": 123
|
|
950
|
+
// },
|
|
951
|
+
// "max_notional": {
|
|
952
|
+
// "PERP_BTC_USDC": 123,
|
|
953
|
+
// "PERP_ETH_USDC": 123,
|
|
954
|
+
// "PERP_NEAR_USDC": 123
|
|
955
|
+
// }
|
|
956
|
+
// }
|
|
957
|
+
// }
|
|
958
|
+
//
|
|
959
|
+
const data = this.safeDict(response, 'data', {});
|
|
960
|
+
const maker = this.safeString(data, 'futures_maker_fee_rate');
|
|
961
|
+
const taker = this.safeString(data, 'futures_taker_fee_rate');
|
|
962
|
+
const result = {};
|
|
963
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
|
964
|
+
const symbol = this.symbols[i];
|
|
965
|
+
result[symbol] = {
|
|
966
|
+
'info': response,
|
|
967
|
+
'symbol': symbol,
|
|
968
|
+
'maker': this.parseNumber(Precise["default"].stringDiv(maker, '10000')),
|
|
969
|
+
'taker': this.parseNumber(Precise["default"].stringDiv(taker, '10000')),
|
|
970
|
+
'percentage': true,
|
|
971
|
+
'tierBased': true,
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
return result;
|
|
975
|
+
}
|
|
976
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
977
|
+
/**
|
|
978
|
+
* @method
|
|
979
|
+
* @name woofipro#fetchOrderBook
|
|
980
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
981
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/orderbook-snapshot
|
|
982
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
983
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
984
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
985
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
986
|
+
*/
|
|
987
|
+
await this.loadMarkets();
|
|
988
|
+
const market = this.market(symbol);
|
|
989
|
+
const request = {
|
|
990
|
+
'symbol': market['id'],
|
|
991
|
+
};
|
|
992
|
+
if (limit !== undefined) {
|
|
993
|
+
limit = Math.min(limit, 1000);
|
|
994
|
+
request['max_level'] = limit;
|
|
995
|
+
}
|
|
996
|
+
const response = await this.v1PrivateGetOrderbookSymbol(this.extend(request, params));
|
|
997
|
+
//
|
|
998
|
+
// {
|
|
999
|
+
// "success": true,
|
|
1000
|
+
// "timestamp": 1702989203989,
|
|
1001
|
+
// "data": {
|
|
1002
|
+
// "asks": [{
|
|
1003
|
+
// "price": 10669.4,
|
|
1004
|
+
// "quantity": 1.56263218
|
|
1005
|
+
// }],
|
|
1006
|
+
// "bids": [{
|
|
1007
|
+
// "price": 10669.4,
|
|
1008
|
+
// "quantity": 1.56263218
|
|
1009
|
+
// }],
|
|
1010
|
+
// "timestamp": 123
|
|
1011
|
+
// }
|
|
1012
|
+
// }
|
|
1013
|
+
//
|
|
1014
|
+
const data = this.safeDict(response, 'data', {});
|
|
1015
|
+
const timestamp = this.safeInteger(data, 'timestamp');
|
|
1016
|
+
return this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity');
|
|
1017
|
+
}
|
|
1018
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
1019
|
+
return [
|
|
1020
|
+
this.safeInteger(ohlcv, 'start_timestamp'),
|
|
1021
|
+
this.safeNumber(ohlcv, 'open'),
|
|
1022
|
+
this.safeNumber(ohlcv, 'high'),
|
|
1023
|
+
this.safeNumber(ohlcv, 'low'),
|
|
1024
|
+
this.safeNumber(ohlcv, 'close'),
|
|
1025
|
+
this.safeNumber(ohlcv, 'volume'),
|
|
1026
|
+
];
|
|
1027
|
+
}
|
|
1028
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
1029
|
+
/**
|
|
1030
|
+
* @method
|
|
1031
|
+
* @name woofipro#fetchOHLCV
|
|
1032
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-kline
|
|
1033
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1034
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
1035
|
+
* @param {string} timeframe the length of time each candle represents
|
|
1036
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
1037
|
+
* @param {int} [limit] max=1000, max=100 when since is defined and is less than (now - (999 * (timeframe in ms)))
|
|
1038
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1039
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
1040
|
+
*/
|
|
1041
|
+
await this.loadMarkets();
|
|
1042
|
+
const market = this.market(symbol);
|
|
1043
|
+
const request = {
|
|
1044
|
+
'symbol': market['id'],
|
|
1045
|
+
'type': this.safeString(this.timeframes, timeframe, timeframe),
|
|
1046
|
+
};
|
|
1047
|
+
if (limit !== undefined) {
|
|
1048
|
+
request['limit'] = Math.min(limit, 1000);
|
|
1049
|
+
}
|
|
1050
|
+
const response = await this.v1PrivateGetKline(this.extend(request, params));
|
|
1051
|
+
const data = this.safeDict(response, 'data', {});
|
|
1052
|
+
//
|
|
1053
|
+
// {
|
|
1054
|
+
// "success": true,
|
|
1055
|
+
// "timestamp": 1702989203989,
|
|
1056
|
+
// "data": {
|
|
1057
|
+
// "rows": [{
|
|
1058
|
+
// "open": 66166.23,
|
|
1059
|
+
// "close": 66124.56,
|
|
1060
|
+
// "low": 66038.06,
|
|
1061
|
+
// "high": 66176.97,
|
|
1062
|
+
// "volume": 23.45528526,
|
|
1063
|
+
// "amount": 1550436.21725288,
|
|
1064
|
+
// "symbol": "PERP_BTC_USDC",
|
|
1065
|
+
// "type": "1m",
|
|
1066
|
+
// "start_timestamp": 1636388220000,
|
|
1067
|
+
// "end_timestamp": 1636388280000
|
|
1068
|
+
// }]
|
|
1069
|
+
// }
|
|
1070
|
+
// }
|
|
1071
|
+
//
|
|
1072
|
+
const rows = this.safeList(data, 'rows', []);
|
|
1073
|
+
return this.parseOHLCVs(rows, market, timeframe, since, limit);
|
|
1074
|
+
}
|
|
1075
|
+
parseOrder(order, market = undefined) {
|
|
1076
|
+
//
|
|
1077
|
+
// Possible input functions:
|
|
1078
|
+
// * createOrder
|
|
1079
|
+
// * createOrders
|
|
1080
|
+
// * cancelOrder
|
|
1081
|
+
// * fetchOrder
|
|
1082
|
+
// * fetchOrders
|
|
1083
|
+
// const isFromFetchOrder = ('order_tag' in order); TO_DO
|
|
1084
|
+
//
|
|
1085
|
+
// stop order after creating it:
|
|
1086
|
+
// {
|
|
1087
|
+
// "orderId": "1578938",
|
|
1088
|
+
// "clientOrderId": "0",
|
|
1089
|
+
// "algoType": "STOP_LOSS",
|
|
1090
|
+
// "quantity": "0.1"
|
|
1091
|
+
// }
|
|
1092
|
+
// stop order after fetching it:
|
|
1093
|
+
// {
|
|
1094
|
+
// "algoOrderId": "1578958",
|
|
1095
|
+
// "clientOrderId": "0",
|
|
1096
|
+
// "rootAlgoOrderId": "1578958",
|
|
1097
|
+
// "parentAlgoOrderId": "0",
|
|
1098
|
+
// "symbol": "SPOT_LTC_USDT",
|
|
1099
|
+
// "orderTag": "default",
|
|
1100
|
+
// "algoType": "STOP_LOSS",
|
|
1101
|
+
// "side": "BUY",
|
|
1102
|
+
// "quantity": "0.1",
|
|
1103
|
+
// "isTriggered": false,
|
|
1104
|
+
// "triggerPrice": "100",
|
|
1105
|
+
// "triggerStatus": "USELESS",
|
|
1106
|
+
// "type": "LIMIT",
|
|
1107
|
+
// "rootAlgoStatus": "CANCELLED",
|
|
1108
|
+
// "algoStatus": "CANCELLED",
|
|
1109
|
+
// "triggerPriceType": "MARKET_PRICE",
|
|
1110
|
+
// "price": "75",
|
|
1111
|
+
// "triggerTime": "0",
|
|
1112
|
+
// "totalExecutedQuantity": "0",
|
|
1113
|
+
// "averageExecutedPrice": "0",
|
|
1114
|
+
// "totalFee": "0",
|
|
1115
|
+
// "feeAsset": '',
|
|
1116
|
+
// "reduceOnly": false,
|
|
1117
|
+
// "createdTime": "1686149609.744",
|
|
1118
|
+
// "updatedTime": "1686149903.362"
|
|
1119
|
+
// }
|
|
1120
|
+
//
|
|
1121
|
+
const timestamp = this.safeIntegerN(order, ['timestamp', 'created_time', 'createdTime']);
|
|
1122
|
+
const orderId = this.safeStringN(order, ['order_id', 'orderId', 'algoOrderId']);
|
|
1123
|
+
const clientOrderId = this.omitZero(this.safeString2(order, 'client_order_id', 'clientOrderId')); // Somehow, this always returns 0 for limit order
|
|
1124
|
+
const marketId = this.safeString(order, 'symbol');
|
|
1125
|
+
market = this.safeMarket(marketId, market);
|
|
1126
|
+
const symbol = market['symbol'];
|
|
1127
|
+
const price = this.safeString2(order, 'order_price', 'price');
|
|
1128
|
+
const amount = this.safeString2(order, 'order_quantity', 'quantity'); // This is base amount
|
|
1129
|
+
const cost = this.safeString2(order, 'order_amount', 'amount'); // This is quote amount
|
|
1130
|
+
const orderType = this.safeStringLower2(order, 'order_type', 'type');
|
|
1131
|
+
let status = this.safeValue2(order, 'status', 'algoStatus');
|
|
1132
|
+
const success = this.safeBool(order, 'success');
|
|
1133
|
+
if (success !== undefined) {
|
|
1134
|
+
status = (success) ? 'NEW' : 'REJECTED';
|
|
1135
|
+
}
|
|
1136
|
+
const side = this.safeStringLower(order, 'side');
|
|
1137
|
+
const filled = this.omitZero(this.safeValue2(order, 'executed', 'totalExecutedQuantity'));
|
|
1138
|
+
const average = this.omitZero(this.safeString2(order, 'average_executed_price', 'averageExecutedPrice'));
|
|
1139
|
+
const remaining = Precise["default"].stringSub(cost, filled);
|
|
1140
|
+
const fee = this.safeValue2(order, 'total_fee', 'totalFee');
|
|
1141
|
+
const feeCurrency = this.safeString2(order, 'fee_asset', 'feeAsset');
|
|
1142
|
+
const transactions = this.safeValue(order, 'Transactions');
|
|
1143
|
+
const stopPrice = this.safeNumber(order, 'triggerPrice');
|
|
1144
|
+
let takeProfitPrice = undefined;
|
|
1145
|
+
let stopLossPrice = undefined;
|
|
1146
|
+
const childOrders = this.safeValue(order, 'childOrders');
|
|
1147
|
+
if (childOrders !== undefined) {
|
|
1148
|
+
const first = this.safeValue(childOrders, 0);
|
|
1149
|
+
const innerChildOrders = this.safeValue(first, 'childOrders', []);
|
|
1150
|
+
const innerChildOrdersLength = innerChildOrders.length;
|
|
1151
|
+
if (innerChildOrdersLength > 0) {
|
|
1152
|
+
const takeProfitOrder = this.safeValue(innerChildOrders, 0);
|
|
1153
|
+
const stopLossOrder = this.safeValue(innerChildOrders, 1);
|
|
1154
|
+
takeProfitPrice = this.safeNumber(takeProfitOrder, 'triggerPrice');
|
|
1155
|
+
stopLossPrice = this.safeNumber(stopLossOrder, 'triggerPrice');
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
const lastUpdateTimestamp = this.safeInteger2(order, 'updatedTime', 'updated_time');
|
|
1159
|
+
return this.safeOrder({
|
|
1160
|
+
'id': orderId,
|
|
1161
|
+
'clientOrderId': clientOrderId,
|
|
1162
|
+
'timestamp': timestamp,
|
|
1163
|
+
'datetime': this.iso8601(timestamp),
|
|
1164
|
+
'lastTradeTimestamp': undefined,
|
|
1165
|
+
'lastUpdateTimestamp': lastUpdateTimestamp,
|
|
1166
|
+
'status': this.parseOrderStatus(status),
|
|
1167
|
+
'symbol': symbol,
|
|
1168
|
+
'type': this.parseOrderType(orderType),
|
|
1169
|
+
'timeInForce': this.parseTimeInForce(orderType),
|
|
1170
|
+
'postOnly': undefined,
|
|
1171
|
+
'reduceOnly': this.safeBool(order, 'reduce_only'),
|
|
1172
|
+
'side': side,
|
|
1173
|
+
'price': price,
|
|
1174
|
+
'stopPrice': stopPrice,
|
|
1175
|
+
'triggerPrice': stopPrice,
|
|
1176
|
+
'takeProfitPrice': takeProfitPrice,
|
|
1177
|
+
'stopLossPrice': stopLossPrice,
|
|
1178
|
+
'average': average,
|
|
1179
|
+
'amount': amount,
|
|
1180
|
+
'filled': filled,
|
|
1181
|
+
'remaining': remaining,
|
|
1182
|
+
'cost': cost,
|
|
1183
|
+
'trades': transactions,
|
|
1184
|
+
'fee': {
|
|
1185
|
+
'cost': fee,
|
|
1186
|
+
'currency': feeCurrency,
|
|
1187
|
+
},
|
|
1188
|
+
'info': order,
|
|
1189
|
+
}, market);
|
|
1190
|
+
}
|
|
1191
|
+
parseTimeInForce(timeInForce) {
|
|
1192
|
+
const timeInForces = {
|
|
1193
|
+
'ioc': 'IOC',
|
|
1194
|
+
'fok': 'FOK',
|
|
1195
|
+
'post_only': 'PO',
|
|
1196
|
+
};
|
|
1197
|
+
return this.safeString(timeInForces, timeInForce, undefined);
|
|
1198
|
+
}
|
|
1199
|
+
parseOrderStatus(status) {
|
|
1200
|
+
if (status !== undefined) {
|
|
1201
|
+
const statuses = {
|
|
1202
|
+
'NEW': 'open',
|
|
1203
|
+
'FILLED': 'closed',
|
|
1204
|
+
'CANCEL_SENT': 'canceled',
|
|
1205
|
+
'CANCEL_ALL_SENT': 'canceled',
|
|
1206
|
+
'CANCELLED': 'canceled',
|
|
1207
|
+
'PARTIAL_FILLED': 'open',
|
|
1208
|
+
'REJECTED': 'rejected',
|
|
1209
|
+
'INCOMPLETE': 'open',
|
|
1210
|
+
'COMPLETED': 'closed',
|
|
1211
|
+
};
|
|
1212
|
+
return this.safeString(statuses, status, status);
|
|
1213
|
+
}
|
|
1214
|
+
return status;
|
|
1215
|
+
}
|
|
1216
|
+
parseOrderType(type) {
|
|
1217
|
+
const types = {
|
|
1218
|
+
'LIMIT': 'limit',
|
|
1219
|
+
'MARKET': 'market',
|
|
1220
|
+
'POST_ONLY': 'limit',
|
|
1221
|
+
};
|
|
1222
|
+
return this.safeStringLower(types, type, type);
|
|
1223
|
+
}
|
|
1224
|
+
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1225
|
+
/**
|
|
1226
|
+
* @method
|
|
1227
|
+
* @ignore
|
|
1228
|
+
* @name woofipro#createOrderRequest
|
|
1229
|
+
* @description helper function to build the request
|
|
1230
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1231
|
+
* @param {string} type 'market' or 'limit'
|
|
1232
|
+
* @param {string} side 'buy' or 'sell'
|
|
1233
|
+
* @param {float} amount how much you want to trade in units of the base currency
|
|
1234
|
+
* @param {float} [price] the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1235
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1236
|
+
* @returns {object} request to be sent to the exchange
|
|
1237
|
+
*/
|
|
1238
|
+
const reduceOnly = this.safeBool2(params, 'reduceOnly', 'reduce_only');
|
|
1239
|
+
const orderType = type.toUpperCase();
|
|
1240
|
+
const market = this.market(symbol);
|
|
1241
|
+
const orderSide = side.toUpperCase();
|
|
1242
|
+
const request = {
|
|
1243
|
+
'symbol': market['id'],
|
|
1244
|
+
'side': orderSide,
|
|
1245
|
+
};
|
|
1246
|
+
const stopPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
1247
|
+
const stopLoss = this.safeValue(params, 'stopLoss');
|
|
1248
|
+
const takeProfit = this.safeValue(params, 'takeProfit');
|
|
1249
|
+
const algoType = this.safeString(params, 'algoType');
|
|
1250
|
+
const isStop = stopPrice !== undefined || stopLoss !== undefined || takeProfit !== undefined || (this.safeValue(params, 'childOrders') !== undefined);
|
|
1251
|
+
const isMarket = orderType === 'MARKET';
|
|
1252
|
+
const timeInForce = this.safeStringLower(params, 'timeInForce');
|
|
1253
|
+
const postOnly = this.isPostOnly(isMarket, undefined, params);
|
|
1254
|
+
const orderQtyKey = isStop ? 'quantity' : 'order_quantity';
|
|
1255
|
+
const priceKey = isStop ? 'price' : 'order_price';
|
|
1256
|
+
const typeKey = isStop ? 'type' : 'order_type';
|
|
1257
|
+
request[typeKey] = orderType; // LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
|
|
1258
|
+
if (!isStop) {
|
|
1259
|
+
if (postOnly) {
|
|
1260
|
+
request['order_type'] = 'POST_ONLY';
|
|
1261
|
+
}
|
|
1262
|
+
else if (timeInForce === 'fok') {
|
|
1263
|
+
request['order_type'] = 'FOK';
|
|
1264
|
+
}
|
|
1265
|
+
else if (timeInForce === 'ioc') {
|
|
1266
|
+
request['order_type'] = 'IOC';
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
if (reduceOnly) {
|
|
1270
|
+
request['reduce_only'] = reduceOnly;
|
|
1271
|
+
}
|
|
1272
|
+
if (price !== undefined) {
|
|
1273
|
+
request[priceKey] = this.priceToPrecision(symbol, price);
|
|
1274
|
+
}
|
|
1275
|
+
if (isMarket && !isStop) {
|
|
1276
|
+
request[orderQtyKey] = this.amountToPrecision(symbol, amount);
|
|
1277
|
+
}
|
|
1278
|
+
else if (algoType !== 'POSITIONAL_TP_SL') {
|
|
1279
|
+
request[orderQtyKey] = this.amountToPrecision(symbol, amount);
|
|
1280
|
+
}
|
|
1281
|
+
const clientOrderId = this.safeStringN(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
|
|
1282
|
+
if (clientOrderId !== undefined) {
|
|
1283
|
+
request['client_order_id'] = clientOrderId;
|
|
1284
|
+
}
|
|
1285
|
+
if (stopPrice !== undefined) {
|
|
1286
|
+
request['trigger_price'] = this.priceToPrecision(symbol, stopPrice);
|
|
1287
|
+
request['algo_type'] = 'STOP';
|
|
1288
|
+
}
|
|
1289
|
+
else if ((stopLoss !== undefined) || (takeProfit !== undefined)) {
|
|
1290
|
+
request['algo_type'] = 'TP_SL';
|
|
1291
|
+
const outterOrder = {
|
|
1292
|
+
'symbol': market['id'],
|
|
1293
|
+
'reduce_only': false,
|
|
1294
|
+
'algo_type': 'POSITIONAL_TP_SL',
|
|
1295
|
+
'child_orders': [],
|
|
1296
|
+
};
|
|
1297
|
+
const closeSide = (orderSide === 'BUY') ? 'SELL' : 'BUY';
|
|
1298
|
+
if (stopLoss !== undefined) {
|
|
1299
|
+
const stopLossPrice = this.safeNumber2(stopLoss, 'triggerPrice', 'price', stopLoss);
|
|
1300
|
+
const stopLossOrder = {
|
|
1301
|
+
'side': closeSide,
|
|
1302
|
+
'algo_type': 'TP_SL',
|
|
1303
|
+
'trigger_price': this.priceToPrecision(symbol, stopLossPrice),
|
|
1304
|
+
'type': 'LIMIT',
|
|
1305
|
+
'reduce_only': true,
|
|
1306
|
+
};
|
|
1307
|
+
outterOrder['child_orders'].push(stopLossOrder);
|
|
1308
|
+
}
|
|
1309
|
+
if (takeProfit !== undefined) {
|
|
1310
|
+
const takeProfitPrice = this.safeNumber2(takeProfit, 'triggerPrice', 'price', takeProfit);
|
|
1311
|
+
const takeProfitOrder = {
|
|
1312
|
+
'side': closeSide,
|
|
1313
|
+
'algo_type': 'TP_SL',
|
|
1314
|
+
'trigger_price': this.priceToPrecision(symbol, takeProfitPrice),
|
|
1315
|
+
'type': 'LIMIT',
|
|
1316
|
+
'reduce_only': true,
|
|
1317
|
+
};
|
|
1318
|
+
outterOrder['child_orders'].push(takeProfitOrder);
|
|
1319
|
+
}
|
|
1320
|
+
request['child_orders'] = [outterOrder];
|
|
1321
|
+
}
|
|
1322
|
+
params = this.omit(params, ['reduceOnly', 'reduce_only', 'clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLoss', 'takeProfit']);
|
|
1323
|
+
return this.extend(request, params);
|
|
1324
|
+
}
|
|
1325
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1326
|
+
/**
|
|
1327
|
+
* @method
|
|
1328
|
+
* @name woofipro#createOrder
|
|
1329
|
+
* @description create a trade order
|
|
1330
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/create-order
|
|
1331
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/create-algo-order
|
|
1332
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1333
|
+
* @param {string} type 'market' or 'limit'
|
|
1334
|
+
* @param {string} side 'buy' or 'sell'
|
|
1335
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1336
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1337
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1338
|
+
* @param {float} [params.triggerPrice] The price a trigger order is triggered at
|
|
1339
|
+
* @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only)
|
|
1340
|
+
* @param {float} [params.takeProfit.triggerPrice] take profit trigger price
|
|
1341
|
+
* @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only)
|
|
1342
|
+
* @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
|
|
1343
|
+
* @param {float} [params.algoType] 'STOP'or 'TP_SL' or 'POSITIONAL_TP_SL'
|
|
1344
|
+
* @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
|
|
1345
|
+
* @param {string} [params.clientOrderId] a unique id for the order
|
|
1346
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1347
|
+
*/
|
|
1348
|
+
await this.loadMarkets();
|
|
1349
|
+
const market = this.market(symbol);
|
|
1350
|
+
const request = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
1351
|
+
const stopPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
1352
|
+
const stopLoss = this.safeValue(params, 'stopLoss');
|
|
1353
|
+
const takeProfit = this.safeValue(params, 'takeProfit');
|
|
1354
|
+
const isStop = stopPrice !== undefined || stopLoss !== undefined || takeProfit !== undefined || (this.safeValue(params, 'childOrders') !== undefined);
|
|
1355
|
+
let response = undefined;
|
|
1356
|
+
if (isStop) {
|
|
1357
|
+
response = await this.v1PrivatePostAlgoOrder(request);
|
|
1358
|
+
//
|
|
1359
|
+
// {
|
|
1360
|
+
// "success": true,
|
|
1361
|
+
// "timestamp": 1702989203989,
|
|
1362
|
+
// "data": {
|
|
1363
|
+
// "order_id": 13,
|
|
1364
|
+
// "client_order_id": "testclientid",
|
|
1365
|
+
// "algo_type": "STOP",
|
|
1366
|
+
// "quantity": 100.12
|
|
1367
|
+
// }
|
|
1368
|
+
// }
|
|
1369
|
+
//
|
|
1370
|
+
}
|
|
1371
|
+
else {
|
|
1372
|
+
response = await this.v1PrivatePostOrder(request);
|
|
1373
|
+
//
|
|
1374
|
+
// {
|
|
1375
|
+
// "success": true,
|
|
1376
|
+
// "timestamp": 1702989203989,
|
|
1377
|
+
// "data": {
|
|
1378
|
+
// "order_id": 13,
|
|
1379
|
+
// "client_order_id": "testclientid",
|
|
1380
|
+
// "order_type": "LIMIT",
|
|
1381
|
+
// "order_price": 100.12,
|
|
1382
|
+
// "order_quantity": 0.987654,
|
|
1383
|
+
// "order_amount": 0.8,
|
|
1384
|
+
// "error_message": "none"
|
|
1385
|
+
// }
|
|
1386
|
+
// }
|
|
1387
|
+
//
|
|
1388
|
+
}
|
|
1389
|
+
const data = this.safeDict(response, 'data');
|
|
1390
|
+
data['timestamp'] = this.safeInteger(response, 'timestamp');
|
|
1391
|
+
const order = this.parseOrder(data, market);
|
|
1392
|
+
order['type'] = type;
|
|
1393
|
+
return order;
|
|
1394
|
+
}
|
|
1395
|
+
async createOrders(orders, params = {}) {
|
|
1396
|
+
/**
|
|
1397
|
+
* @method
|
|
1398
|
+
* @name woofipro#createOrders
|
|
1399
|
+
* @description *contract only* create a list of trade orders
|
|
1400
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/batch-create-order
|
|
1401
|
+
* @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
|
1402
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1403
|
+
*/
|
|
1404
|
+
await this.loadMarkets();
|
|
1405
|
+
const ordersRequests = [];
|
|
1406
|
+
for (let i = 0; i < orders.length; i++) {
|
|
1407
|
+
const rawOrder = orders[i];
|
|
1408
|
+
const marketId = this.safeString(rawOrder, 'symbol');
|
|
1409
|
+
const type = this.safeString(rawOrder, 'type');
|
|
1410
|
+
const side = this.safeString(rawOrder, 'side');
|
|
1411
|
+
const amount = this.safeValue(rawOrder, 'amount');
|
|
1412
|
+
const price = this.safeValue(rawOrder, 'price');
|
|
1413
|
+
const orderParams = this.safeDict(rawOrder, 'params', {});
|
|
1414
|
+
const stopPrice = this.safeString2(orderParams, 'triggerPrice', 'stopPrice');
|
|
1415
|
+
const stopLoss = this.safeValue(orderParams, 'stopLoss');
|
|
1416
|
+
const takeProfit = this.safeValue(orderParams, 'takeProfit');
|
|
1417
|
+
const isStop = stopPrice !== undefined || stopLoss !== undefined || takeProfit !== undefined || (this.safeValue(orderParams, 'childOrders') !== undefined);
|
|
1418
|
+
if (isStop) {
|
|
1419
|
+
throw new errors.NotSupported(this.id + 'createOrders() only support non-stop order');
|
|
1420
|
+
}
|
|
1421
|
+
const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
|
|
1422
|
+
ordersRequests.push(orderRequest);
|
|
1423
|
+
}
|
|
1424
|
+
const request = {
|
|
1425
|
+
'orders': ordersRequests,
|
|
1426
|
+
};
|
|
1427
|
+
const response = await this.v1PrivatePostBatchOrder(this.extend(request, params));
|
|
1428
|
+
//
|
|
1429
|
+
// {
|
|
1430
|
+
// "success": true,
|
|
1431
|
+
// "timestamp": 1702989203989,
|
|
1432
|
+
// "data": {
|
|
1433
|
+
// "rows": [{
|
|
1434
|
+
// "order_id": 13,
|
|
1435
|
+
// "client_order_id": "testclientid",
|
|
1436
|
+
// "order_type": "LIMIT",
|
|
1437
|
+
// "order_price": 100.12,
|
|
1438
|
+
// "order_quantity": 0.987654,
|
|
1439
|
+
// "order_amount": 0.8,
|
|
1440
|
+
// "error_message": "none"
|
|
1441
|
+
// }]
|
|
1442
|
+
// }
|
|
1443
|
+
// }
|
|
1444
|
+
//
|
|
1445
|
+
const data = this.safeDict(response, 'data', {});
|
|
1446
|
+
const rows = this.safeList(data, 'rows', []);
|
|
1447
|
+
return this.parseOrders(rows);
|
|
1448
|
+
}
|
|
1449
|
+
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
1450
|
+
/**
|
|
1451
|
+
* @method
|
|
1452
|
+
* @name woofipro#editOrder
|
|
1453
|
+
* @description edit a trade order
|
|
1454
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/edit-order
|
|
1455
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/edit-algo-order
|
|
1456
|
+
* @param {string} id order id
|
|
1457
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1458
|
+
* @param {string} type 'market' or 'limit'
|
|
1459
|
+
* @param {string} side 'buy' or 'sell'
|
|
1460
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1461
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1462
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1463
|
+
* @param {float} [params.triggerPrice] The price a trigger order is triggered at
|
|
1464
|
+
* @param {float} [params.stopLossPrice] price to trigger stop-loss orders
|
|
1465
|
+
* @param {float} [params.takeProfitPrice] price to trigger take-profit orders
|
|
1466
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1467
|
+
*/
|
|
1468
|
+
await this.loadMarkets();
|
|
1469
|
+
const market = this.market(symbol);
|
|
1470
|
+
const request = {
|
|
1471
|
+
'order_id': id,
|
|
1472
|
+
};
|
|
1473
|
+
const stopPrice = this.safeStringN(params, ['triggerPrice', 'stopPrice', 'takeProfitPrice', 'stopLossPrice']);
|
|
1474
|
+
if (stopPrice !== undefined) {
|
|
1475
|
+
request['triggerPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
1476
|
+
}
|
|
1477
|
+
const isStop = (stopPrice !== undefined) || (this.safeValue(params, 'childOrders') !== undefined);
|
|
1478
|
+
const orderQtyKey = isStop ? 'quantity' : 'order_quantity';
|
|
1479
|
+
const priceKey = isStop ? 'price' : 'order_price';
|
|
1480
|
+
if (price !== undefined) {
|
|
1481
|
+
request[priceKey] = this.priceToPrecision(symbol, price);
|
|
1482
|
+
}
|
|
1483
|
+
if (amount !== undefined) {
|
|
1484
|
+
request[orderQtyKey] = this.amountToPrecision(symbol, amount);
|
|
1485
|
+
}
|
|
1486
|
+
params = this.omit(params, ['stopPrice', 'triggerPrice', 'takeProfitPrice', 'stopLossPrice', 'trailingTriggerPrice', 'trailingAmount', 'trailingPercent']);
|
|
1487
|
+
let response = undefined;
|
|
1488
|
+
if (isStop) {
|
|
1489
|
+
response = await this.v1PrivatePutAlgoOrder(this.extend(request, params));
|
|
1490
|
+
}
|
|
1491
|
+
else {
|
|
1492
|
+
request['symbol'] = market['id'];
|
|
1493
|
+
request['side'] = side.toUpperCase();
|
|
1494
|
+
const orderType = type.toUpperCase();
|
|
1495
|
+
const timeInForce = this.safeStringLower(params, 'timeInForce');
|
|
1496
|
+
const isMarket = orderType === 'MARKET';
|
|
1497
|
+
const postOnly = this.isPostOnly(isMarket, undefined, params);
|
|
1498
|
+
if (postOnly) {
|
|
1499
|
+
request['order_type'] = 'POST_ONLY';
|
|
1500
|
+
}
|
|
1501
|
+
else if (timeInForce === 'fok') {
|
|
1502
|
+
request['order_type'] = 'FOK';
|
|
1503
|
+
}
|
|
1504
|
+
else if (timeInForce === 'ioc') {
|
|
1505
|
+
request['order_type'] = 'IOC';
|
|
1506
|
+
}
|
|
1507
|
+
else {
|
|
1508
|
+
request['order_type'] = orderType;
|
|
1509
|
+
}
|
|
1510
|
+
const clientOrderId = this.safeStringN(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
|
|
1511
|
+
params = this.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce']);
|
|
1512
|
+
if (clientOrderId !== undefined) {
|
|
1513
|
+
request['client_order_id'] = clientOrderId;
|
|
1514
|
+
}
|
|
1515
|
+
// request['side'] = side.toUpperCase ();
|
|
1516
|
+
// request['symbol'] = market['id'];
|
|
1517
|
+
response = await this.v1PrivatePutOrder(this.extend(request, params));
|
|
1518
|
+
}
|
|
1519
|
+
//
|
|
1520
|
+
// {
|
|
1521
|
+
// "success": true,
|
|
1522
|
+
// "timestamp": 1702989203989,
|
|
1523
|
+
// "data": {
|
|
1524
|
+
// "status": "EDIT_SENT"
|
|
1525
|
+
// }
|
|
1526
|
+
// }
|
|
1527
|
+
//
|
|
1528
|
+
const data = this.safeDict(response, 'data', {});
|
|
1529
|
+
data['timestamp'] = this.safeInteger(response, 'timestamp');
|
|
1530
|
+
return this.parseOrder(data, market);
|
|
1531
|
+
}
|
|
1532
|
+
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1533
|
+
/**
|
|
1534
|
+
* @method
|
|
1535
|
+
* @name woofipro#cancelOrder
|
|
1536
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-order
|
|
1537
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-order-by-client_order_id
|
|
1538
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-algo-order
|
|
1539
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-algo-order-by-client_order_id
|
|
1540
|
+
* @description cancels an open order
|
|
1541
|
+
* @param {string} id order id
|
|
1542
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1543
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1544
|
+
* @param {boolean} [params.trigger] whether the order is a stop/algo order
|
|
1545
|
+
* @param {string} [params.clientOrderId] a unique id for the order
|
|
1546
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1547
|
+
*/
|
|
1548
|
+
const stop = this.safeBool2(params, 'stop', 'trigger', false);
|
|
1549
|
+
params = this.omit(params, ['stop', 'trigger']);
|
|
1550
|
+
if (!stop && (symbol === undefined)) {
|
|
1551
|
+
throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
|
|
1552
|
+
}
|
|
1553
|
+
await this.loadMarkets();
|
|
1554
|
+
let market = undefined;
|
|
1555
|
+
if (symbol !== undefined) {
|
|
1556
|
+
market = this.market(symbol);
|
|
1557
|
+
}
|
|
1558
|
+
const request = {
|
|
1559
|
+
'symbol': market['id'],
|
|
1560
|
+
};
|
|
1561
|
+
const clientOrderIdUnified = this.safeString2(params, 'clOrdID', 'clientOrderId');
|
|
1562
|
+
const clientOrderIdExchangeSpecific = this.safeString(params, 'client_order_id', clientOrderIdUnified);
|
|
1563
|
+
const isByClientOrder = clientOrderIdExchangeSpecific !== undefined;
|
|
1564
|
+
let response = undefined;
|
|
1565
|
+
if (stop) {
|
|
1566
|
+
if (isByClientOrder) {
|
|
1567
|
+
request['client_order_id'] = clientOrderIdExchangeSpecific;
|
|
1568
|
+
params = this.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
|
|
1569
|
+
response = await this.v1PrivateDeleteAlgoClientOrder(this.extend(request, params));
|
|
1570
|
+
}
|
|
1571
|
+
else {
|
|
1572
|
+
request['order_id'] = id;
|
|
1573
|
+
response = await this.v1PrivateDeleteAlgoOrder(this.extend(request, params));
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
else {
|
|
1577
|
+
if (isByClientOrder) {
|
|
1578
|
+
request['client_order_id'] = clientOrderIdExchangeSpecific;
|
|
1579
|
+
params = this.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
|
|
1580
|
+
response = await this.v1PrivateDeleteClientOrder(this.extend(request, params));
|
|
1581
|
+
}
|
|
1582
|
+
else {
|
|
1583
|
+
request['order_id'] = id;
|
|
1584
|
+
response = await this.v1PrivateDeleteOrder(this.extend(request, params));
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
//
|
|
1588
|
+
// {
|
|
1589
|
+
// "success": true,
|
|
1590
|
+
// "timestamp": 1702989203989,
|
|
1591
|
+
// "data": {
|
|
1592
|
+
// "status": "CANCEL_SENT"
|
|
1593
|
+
// }
|
|
1594
|
+
// }
|
|
1595
|
+
//
|
|
1596
|
+
// {
|
|
1597
|
+
// "success": true,
|
|
1598
|
+
// "timestamp": 1702989203989,
|
|
1599
|
+
// "status": "CANCEL_SENT"
|
|
1600
|
+
// }
|
|
1601
|
+
//
|
|
1602
|
+
const extendParams = { 'symbol': symbol };
|
|
1603
|
+
if (isByClientOrder) {
|
|
1604
|
+
extendParams['client_order_id'] = clientOrderIdExchangeSpecific;
|
|
1605
|
+
}
|
|
1606
|
+
else {
|
|
1607
|
+
extendParams['id'] = id;
|
|
1608
|
+
}
|
|
1609
|
+
if (stop) {
|
|
1610
|
+
return this.extend(this.parseOrder(response), extendParams);
|
|
1611
|
+
}
|
|
1612
|
+
const data = this.safeDict(response, 'data', {});
|
|
1613
|
+
return this.extend(this.parseOrder(data), extendParams);
|
|
1614
|
+
}
|
|
1615
|
+
async cancelOrders(ids, symbol = undefined, params = {}) {
|
|
1616
|
+
/**
|
|
1617
|
+
* @method
|
|
1618
|
+
* @name woofipro#cancelOrders
|
|
1619
|
+
* @description cancel multiple orders
|
|
1620
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/batch-cancel-orders
|
|
1621
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/batch-cancel-orders-by-client_order_id
|
|
1622
|
+
* @param {string[]} ids order ids
|
|
1623
|
+
* @param {string} [symbol] unified market symbol
|
|
1624
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1625
|
+
* @param {string[]} [params.client_order_ids] max length 10 e.g. ["my_id_1","my_id_2"], encode the double quotes. No space after comma
|
|
1626
|
+
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1627
|
+
*/
|
|
1628
|
+
await this.loadMarkets();
|
|
1629
|
+
const clientOrderIds = this.safeListN(params, ['clOrdIDs', 'clientOrderIds', 'client_order_ids']);
|
|
1630
|
+
params = this.omit(params, ['clOrdIDs', 'clientOrderIds', 'client_order_ids']);
|
|
1631
|
+
const request = {};
|
|
1632
|
+
let response = undefined;
|
|
1633
|
+
if (clientOrderIds) {
|
|
1634
|
+
request['client_order_ids'] = clientOrderIds.join(',');
|
|
1635
|
+
response = await this.v1PrivateDeleteClientBatchOrder(this.extend(request, params));
|
|
1636
|
+
}
|
|
1637
|
+
else {
|
|
1638
|
+
request['order_ids'] = ids.join(',');
|
|
1639
|
+
response = await this.v1PrivateDeleteBatchOrder(this.extend(request, params));
|
|
1640
|
+
}
|
|
1641
|
+
//
|
|
1642
|
+
// {
|
|
1643
|
+
// "success": true,
|
|
1644
|
+
// "timestamp": 1702989203989,
|
|
1645
|
+
// "data": {
|
|
1646
|
+
// "status": "CANCEL_ALL_SENT"
|
|
1647
|
+
// }
|
|
1648
|
+
// }
|
|
1649
|
+
//
|
|
1650
|
+
return response;
|
|
1651
|
+
}
|
|
1652
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1653
|
+
/**
|
|
1654
|
+
* @method
|
|
1655
|
+
* @name woofipro#cancelAllOrders
|
|
1656
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-all-pending-algo-orders
|
|
1657
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/cancel-orders-in-bulk
|
|
1658
|
+
* @description cancel all open orders in a market
|
|
1659
|
+
* @param {string} symbol unified market symbol
|
|
1660
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1661
|
+
* @param {boolean} [params.trigger] whether the order is a stop/algo order
|
|
1662
|
+
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1663
|
+
*/
|
|
1664
|
+
await this.loadMarkets();
|
|
1665
|
+
const stop = this.safeBool2(params, 'stop', 'trigger');
|
|
1666
|
+
params = this.omit(params, ['stop', 'trigger']);
|
|
1667
|
+
const request = {};
|
|
1668
|
+
if (symbol !== undefined) {
|
|
1669
|
+
const market = this.market(symbol);
|
|
1670
|
+
request['symbol'] = market['id'];
|
|
1671
|
+
}
|
|
1672
|
+
let response = undefined;
|
|
1673
|
+
if (stop) {
|
|
1674
|
+
response = await this.v1PrivateDeleteAlgoOrders(this.extend(request, params));
|
|
1675
|
+
}
|
|
1676
|
+
else {
|
|
1677
|
+
response = await this.v1PrivateDeleteOrders(this.extend(request, params));
|
|
1678
|
+
}
|
|
1679
|
+
// stop
|
|
1680
|
+
// {
|
|
1681
|
+
// "success": true,
|
|
1682
|
+
// "timestamp": 1702989203989,
|
|
1683
|
+
// "status": "CANCEL_ALL_SENT"
|
|
1684
|
+
// }
|
|
1685
|
+
//
|
|
1686
|
+
// {
|
|
1687
|
+
// "success": true,
|
|
1688
|
+
// "timestamp": 1702989203989,
|
|
1689
|
+
// "data": {
|
|
1690
|
+
// "status": "CANCEL_ALL_SENT"
|
|
1691
|
+
// }
|
|
1692
|
+
// }
|
|
1693
|
+
//
|
|
1694
|
+
return response;
|
|
1695
|
+
}
|
|
1696
|
+
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1697
|
+
/**
|
|
1698
|
+
* @method
|
|
1699
|
+
* @name woofipro#fetchOrder
|
|
1700
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-order-by-order_id
|
|
1701
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-order-by-client_order_id
|
|
1702
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-order-by-order_id
|
|
1703
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-order-by-client_order_id
|
|
1704
|
+
* @description fetches information on an order made by the user
|
|
1705
|
+
* @param {string} symbol unified symbol of the market the order was made in
|
|
1706
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1707
|
+
* @param {boolean} [params.trigger] whether the order is a stop/algo order
|
|
1708
|
+
* @param {string} [params.clientOrderId] a unique id for the order
|
|
1709
|
+
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1710
|
+
*/
|
|
1711
|
+
await this.loadMarkets();
|
|
1712
|
+
const market = (symbol !== undefined) ? this.market(symbol) : undefined;
|
|
1713
|
+
const stop = this.safeBool2(params, 'stop', 'trigger', false);
|
|
1714
|
+
const request = {};
|
|
1715
|
+
const clientOrderId = this.safeStringN(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
|
|
1716
|
+
params = this.omit(params, ['stop', 'trigger', 'clOrdID', 'clientOrderId', 'client_order_id']);
|
|
1717
|
+
let response = undefined;
|
|
1718
|
+
if (stop) {
|
|
1719
|
+
if (clientOrderId) {
|
|
1720
|
+
request['client_order_id'] = clientOrderId;
|
|
1721
|
+
response = await this.v1PrivateGetAlgoClientOrderClientOrderId(this.extend(request, params));
|
|
1722
|
+
}
|
|
1723
|
+
else {
|
|
1724
|
+
request['oid'] = id;
|
|
1725
|
+
response = await this.v1PrivateGetAlgoOrderOid(this.extend(request, params));
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
else {
|
|
1729
|
+
if (clientOrderId) {
|
|
1730
|
+
request['client_order_id'] = clientOrderId;
|
|
1731
|
+
response = await this.v1PrivateGetClientOrderClientOrderId(this.extend(request, params));
|
|
1732
|
+
}
|
|
1733
|
+
else {
|
|
1734
|
+
request['oid'] = id;
|
|
1735
|
+
response = await this.v1PrivateGetOrderOid(this.extend(request, params));
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
//
|
|
1739
|
+
// {
|
|
1740
|
+
// "success": true,
|
|
1741
|
+
// "timestamp": 1702989203989,
|
|
1742
|
+
// "data": {
|
|
1743
|
+
// "order_id": 78151,
|
|
1744
|
+
// "user_id": 12345,
|
|
1745
|
+
// "price": 0.67772,
|
|
1746
|
+
// "type": "LIMIT",
|
|
1747
|
+
// "quantity": 20,
|
|
1748
|
+
// "amount": 10,
|
|
1749
|
+
// "executed_quantity": 20,
|
|
1750
|
+
// "total_executed_quantity": 20,
|
|
1751
|
+
// "visible_quantity": 1,
|
|
1752
|
+
// "symbol": "PERP_WOO_USDC",
|
|
1753
|
+
// "side": "BUY",
|
|
1754
|
+
// "status": "FILLED",
|
|
1755
|
+
// "total_fee": 0.5,
|
|
1756
|
+
// "fee_asset": "WOO",
|
|
1757
|
+
// "client_order_id": 1,
|
|
1758
|
+
// "average_executed_price": 0.67772,
|
|
1759
|
+
// "created_time": 1653563963000,
|
|
1760
|
+
// "updated_time": 1653564213000,
|
|
1761
|
+
// "realized_pnl": 123
|
|
1762
|
+
// }
|
|
1763
|
+
// }
|
|
1764
|
+
//
|
|
1765
|
+
const orders = this.safeDict(response, 'data', response);
|
|
1766
|
+
return this.parseOrder(orders, market);
|
|
1767
|
+
}
|
|
1768
|
+
async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1769
|
+
/**
|
|
1770
|
+
* @method
|
|
1771
|
+
* @name woofipro#fetchOrders
|
|
1772
|
+
* @description fetches information on multiple orders made by the user
|
|
1773
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-orders
|
|
1774
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-orders
|
|
1775
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1776
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1777
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1778
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1779
|
+
* @param {boolean} [params.trigger] whether the order is a stop/algo order
|
|
1780
|
+
* @param {boolean} [params.is_triggered] whether the order has been triggered (false by default)
|
|
1781
|
+
* @param {string} [params.side] 'buy' or 'sell'
|
|
1782
|
+
* @param {boolean} [params.paginate] set to true if you want to fetch orders with pagination
|
|
1783
|
+
* @param {int} params.until timestamp in ms of the latest order to fetch
|
|
1784
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1785
|
+
*/
|
|
1786
|
+
await this.loadMarkets();
|
|
1787
|
+
let paginate = false;
|
|
1788
|
+
const isTrigger = this.safeBool2(params, 'stop', 'trigger', false);
|
|
1789
|
+
const maxLimit = (isTrigger) ? 100 : 500;
|
|
1790
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOrders', 'paginate');
|
|
1791
|
+
if (paginate) {
|
|
1792
|
+
return await this.fetchPaginatedCallIncremental('fetchOrders', symbol, since, limit, params, 'page', maxLimit);
|
|
1793
|
+
}
|
|
1794
|
+
let request = {};
|
|
1795
|
+
let market = undefined;
|
|
1796
|
+
params = this.omit(params, ['stop', 'trigger']);
|
|
1797
|
+
if (symbol !== undefined) {
|
|
1798
|
+
market = this.market(symbol);
|
|
1799
|
+
request['symbol'] = market['id'];
|
|
1800
|
+
}
|
|
1801
|
+
if (since !== undefined) {
|
|
1802
|
+
request['start_t'] = since;
|
|
1803
|
+
}
|
|
1804
|
+
if (limit !== undefined) {
|
|
1805
|
+
request['size'] = limit;
|
|
1806
|
+
}
|
|
1807
|
+
else {
|
|
1808
|
+
request['size'] = maxLimit;
|
|
1809
|
+
}
|
|
1810
|
+
if (isTrigger) {
|
|
1811
|
+
request['algo_type'] = 'STOP';
|
|
1812
|
+
}
|
|
1813
|
+
[request, params] = this.handleUntilOption('end_t', request, params);
|
|
1814
|
+
let response = undefined;
|
|
1815
|
+
if (isTrigger) {
|
|
1816
|
+
response = await this.v1PrivateGetAlgoOrders(this.extend(request, params));
|
|
1817
|
+
}
|
|
1818
|
+
else {
|
|
1819
|
+
response = await this.v1PrivateGetOrders(this.extend(request, params));
|
|
1820
|
+
}
|
|
1821
|
+
//
|
|
1822
|
+
// {
|
|
1823
|
+
// "success": true,
|
|
1824
|
+
// "timestamp": 1702989203989,
|
|
1825
|
+
// "data": {
|
|
1826
|
+
// "meta": {
|
|
1827
|
+
// "total": 9,
|
|
1828
|
+
// "records_per_page": 25,
|
|
1829
|
+
// "current_page": 1
|
|
1830
|
+
// },
|
|
1831
|
+
// "rows": [{
|
|
1832
|
+
// "order_id": 78151,
|
|
1833
|
+
// "user_id": 12345,
|
|
1834
|
+
// "price": 0.67772,
|
|
1835
|
+
// "type": "LIMIT",
|
|
1836
|
+
// "quantity": 20,
|
|
1837
|
+
// "amount": 10,
|
|
1838
|
+
// "executed_quantity": 20,
|
|
1839
|
+
// "total_executed_quantity": 20,
|
|
1840
|
+
// "visible_quantity": 1,
|
|
1841
|
+
// "symbol": "PERP_WOO_USDC",
|
|
1842
|
+
// "side": "BUY",
|
|
1843
|
+
// "status": "FILLED",
|
|
1844
|
+
// "total_fee": 0.5,
|
|
1845
|
+
// "fee_asset": "WOO",
|
|
1846
|
+
// "client_order_id": 1,
|
|
1847
|
+
// "average_executed_price": 0.67772,
|
|
1848
|
+
// "created_time": 1653563963000,
|
|
1849
|
+
// "updated_time": 1653564213000,
|
|
1850
|
+
// "realized_pnl": 123
|
|
1851
|
+
// }]
|
|
1852
|
+
// }
|
|
1853
|
+
// }
|
|
1854
|
+
//
|
|
1855
|
+
const data = this.safeValue(response, 'data', response);
|
|
1856
|
+
const orders = this.safeList(data, 'rows');
|
|
1857
|
+
return this.parseOrders(orders, market, since, limit);
|
|
1858
|
+
}
|
|
1859
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1860
|
+
/**
|
|
1861
|
+
* @method
|
|
1862
|
+
* @name woofipro#fetchOpenOrders
|
|
1863
|
+
* @description fetches information on multiple orders made by the user
|
|
1864
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-orders
|
|
1865
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-orders
|
|
1866
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1867
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1868
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1869
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1870
|
+
* @param {boolean} [params.trigger] whether the order is a stop/algo order
|
|
1871
|
+
* @param {boolean} [params.is_triggered] whether the order has been triggered (false by default)
|
|
1872
|
+
* @param {string} [params.side] 'buy' or 'sell'
|
|
1873
|
+
* @param {int} params.until timestamp in ms of the latest order to fetch
|
|
1874
|
+
* @param {boolean} [params.paginate] set to true if you want to fetch orders with pagination
|
|
1875
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1876
|
+
*/
|
|
1877
|
+
await this.loadMarkets();
|
|
1878
|
+
const extendedParams = this.extend(params, { 'status': 'INCOMPLETE' });
|
|
1879
|
+
return await this.fetchOrders(symbol, since, limit, extendedParams);
|
|
1880
|
+
}
|
|
1881
|
+
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1882
|
+
/**
|
|
1883
|
+
* @method
|
|
1884
|
+
* @name woofipro#fetchClosedOrders
|
|
1885
|
+
* @description fetches information on multiple orders made by the user
|
|
1886
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-orders
|
|
1887
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-algo-orders
|
|
1888
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1889
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1890
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1891
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1892
|
+
* @param {boolean} [params.trigger] whether the order is a stop/algo order
|
|
1893
|
+
* @param {boolean} [params.is_triggered] whether the order has been triggered (false by default)
|
|
1894
|
+
* @param {string} [params.side] 'buy' or 'sell'
|
|
1895
|
+
* @param {int} params.until timestamp in ms of the latest order to fetch
|
|
1896
|
+
* @param {boolean} [params.paginate] set to true if you want to fetch orders with pagination
|
|
1897
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1898
|
+
*/
|
|
1899
|
+
await this.loadMarkets();
|
|
1900
|
+
const extendedParams = this.extend(params, { 'status': 'COMPLETED' });
|
|
1901
|
+
return await this.fetchOrders(symbol, since, limit, extendedParams);
|
|
1902
|
+
}
|
|
1903
|
+
async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1904
|
+
/**
|
|
1905
|
+
* @method
|
|
1906
|
+
* @name woofipro#fetchOrderTrades
|
|
1907
|
+
* @description fetch all the trades made from a single order
|
|
1908
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-all-trades-of-specific-order
|
|
1909
|
+
* @param {string} id order id
|
|
1910
|
+
* @param {string} symbol unified market symbol
|
|
1911
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1912
|
+
* @param {int} [limit] the maximum number of trades to retrieve
|
|
1913
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1914
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1915
|
+
*/
|
|
1916
|
+
await this.loadMarkets();
|
|
1917
|
+
let market = undefined;
|
|
1918
|
+
if (symbol !== undefined) {
|
|
1919
|
+
market = this.market(symbol);
|
|
1920
|
+
}
|
|
1921
|
+
const request = {
|
|
1922
|
+
'oid': id,
|
|
1923
|
+
};
|
|
1924
|
+
const response = await this.v1PrivateGetOrderOidTrades(this.extend(request, params));
|
|
1925
|
+
//
|
|
1926
|
+
// {
|
|
1927
|
+
// "success": true,
|
|
1928
|
+
// "timestamp": 1702989203989,
|
|
1929
|
+
// "data": {
|
|
1930
|
+
// "rows": [{
|
|
1931
|
+
// "id": 2,
|
|
1932
|
+
// "symbol": "PERP_BTC_USDC",
|
|
1933
|
+
// "fee": 0.0001,
|
|
1934
|
+
// "fee_asset": "USDC",
|
|
1935
|
+
// "side": "BUY",
|
|
1936
|
+
// "order_id": 1,
|
|
1937
|
+
// "executed_price": 123,
|
|
1938
|
+
// "executed_quantity": 0.05,
|
|
1939
|
+
// "executed_timestamp": 1567382401000,
|
|
1940
|
+
// "is_maker": 1,
|
|
1941
|
+
// "realized_pnl": 123
|
|
1942
|
+
// }]
|
|
1943
|
+
// }
|
|
1944
|
+
// }
|
|
1945
|
+
//
|
|
1946
|
+
const data = this.safeDict(response, 'data', {});
|
|
1947
|
+
const trades = this.safeList(data, 'rows', []);
|
|
1948
|
+
return this.parseTrades(trades, market, since, limit, params);
|
|
1949
|
+
}
|
|
1950
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1951
|
+
/**
|
|
1952
|
+
* @method
|
|
1953
|
+
* @name woofipro#fetchMyTrades
|
|
1954
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-trades
|
|
1955
|
+
* @description fetch all trades made by the user
|
|
1956
|
+
* @param {string} symbol unified market symbol
|
|
1957
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
1958
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
1959
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1960
|
+
* @param {boolean} [params.paginate] set to true if you want to fetch trades with pagination
|
|
1961
|
+
* @param {int} params.until timestamp in ms of the latest trade to fetch
|
|
1962
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
1963
|
+
*/
|
|
1964
|
+
await this.loadMarkets();
|
|
1965
|
+
let paginate = false;
|
|
1966
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
|
|
1967
|
+
if (paginate) {
|
|
1968
|
+
return await this.fetchPaginatedCallIncremental('fetchMyTrades', symbol, since, limit, params, 'page', 500);
|
|
1969
|
+
}
|
|
1970
|
+
let request = {};
|
|
1971
|
+
let market = undefined;
|
|
1972
|
+
if (symbol !== undefined) {
|
|
1973
|
+
market = this.market(symbol);
|
|
1974
|
+
request['symbol'] = market['id'];
|
|
1975
|
+
}
|
|
1976
|
+
if (since !== undefined) {
|
|
1977
|
+
request['start_t'] = since;
|
|
1978
|
+
}
|
|
1979
|
+
if (limit !== undefined) {
|
|
1980
|
+
request['size'] = limit;
|
|
1981
|
+
}
|
|
1982
|
+
else {
|
|
1983
|
+
request['size'] = 500;
|
|
1984
|
+
}
|
|
1985
|
+
[request, params] = this.handleUntilOption('end_t', request, params);
|
|
1986
|
+
const response = await this.v1PrivateGetTrades(this.extend(request, params));
|
|
1987
|
+
//
|
|
1988
|
+
// {
|
|
1989
|
+
// "success": true,
|
|
1990
|
+
// "timestamp": 1702989203989,
|
|
1991
|
+
// "data": {
|
|
1992
|
+
// "meta": {
|
|
1993
|
+
// "total": 9,
|
|
1994
|
+
// "records_per_page": 25,
|
|
1995
|
+
// "current_page": 1
|
|
1996
|
+
// },
|
|
1997
|
+
// "rows": [{
|
|
1998
|
+
// "id": 2,
|
|
1999
|
+
// "symbol": "PERP_BTC_USDC",
|
|
2000
|
+
// "fee": 0.0001,
|
|
2001
|
+
// "fee_asset": "USDC",
|
|
2002
|
+
// "side": "BUY",
|
|
2003
|
+
// "order_id": 1,
|
|
2004
|
+
// "executed_price": 123,
|
|
2005
|
+
// "executed_quantity": 0.05,
|
|
2006
|
+
// "executed_timestamp": 1567382401000,
|
|
2007
|
+
// "is_maker": 1,
|
|
2008
|
+
// "realized_pnl": 123
|
|
2009
|
+
// }]
|
|
2010
|
+
// }
|
|
2011
|
+
// }
|
|
2012
|
+
//
|
|
2013
|
+
const data = this.safeDict(response, 'data', {});
|
|
2014
|
+
const trades = this.safeList(data, 'rows', []);
|
|
2015
|
+
return this.parseTrades(trades, market, since, limit, params);
|
|
2016
|
+
}
|
|
2017
|
+
parseBalance(response) {
|
|
2018
|
+
const result = {
|
|
2019
|
+
'info': response,
|
|
2020
|
+
};
|
|
2021
|
+
const balances = this.safeList(response, 'holding', []);
|
|
2022
|
+
for (let i = 0; i < balances.length; i++) {
|
|
2023
|
+
const balance = balances[i];
|
|
2024
|
+
const code = this.safeCurrencyCode(this.safeString(balance, 'token'));
|
|
2025
|
+
const account = this.account();
|
|
2026
|
+
account['total'] = this.safeString(balance, 'holding');
|
|
2027
|
+
account['frozen'] = this.safeString(balance, 'frozen');
|
|
2028
|
+
result[code] = account;
|
|
2029
|
+
}
|
|
2030
|
+
return this.safeBalance(result);
|
|
2031
|
+
}
|
|
2032
|
+
async fetchBalance(params = {}) {
|
|
2033
|
+
/**
|
|
2034
|
+
* @method
|
|
2035
|
+
* @name woofipro#fetchBalance
|
|
2036
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
2037
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-current-holding
|
|
2038
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2039
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
2040
|
+
*/
|
|
2041
|
+
await this.loadMarkets();
|
|
2042
|
+
const response = await this.v1PrivateGetClientHolding(params);
|
|
2043
|
+
//
|
|
2044
|
+
// {
|
|
2045
|
+
// "success": true,
|
|
2046
|
+
// "timestamp": 1702989203989,
|
|
2047
|
+
// "data": {
|
|
2048
|
+
// "holding": [{
|
|
2049
|
+
// "updated_time": 1580794149000,
|
|
2050
|
+
// "token": "BTC",
|
|
2051
|
+
// "holding": -28.000752,
|
|
2052
|
+
// "frozen": 123,
|
|
2053
|
+
// "pending_short": -2000
|
|
2054
|
+
// }]
|
|
2055
|
+
// }
|
|
2056
|
+
// }
|
|
2057
|
+
//
|
|
2058
|
+
const data = this.safeDict(response, 'data');
|
|
2059
|
+
return this.parseBalance(data);
|
|
2060
|
+
}
|
|
2061
|
+
async getAssetHistoryRows(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2062
|
+
await this.loadMarkets();
|
|
2063
|
+
const request = {};
|
|
2064
|
+
let currency = undefined;
|
|
2065
|
+
if (code !== undefined) {
|
|
2066
|
+
currency = this.currency(code);
|
|
2067
|
+
request['balance_token'] = currency['id'];
|
|
2068
|
+
}
|
|
2069
|
+
if (since !== undefined) {
|
|
2070
|
+
request['start_t'] = since;
|
|
2071
|
+
}
|
|
2072
|
+
if (limit !== undefined) {
|
|
2073
|
+
request['pageSize'] = limit;
|
|
2074
|
+
}
|
|
2075
|
+
const transactionType = this.safeString(params, 'type');
|
|
2076
|
+
params = this.omit(params, 'type');
|
|
2077
|
+
if (transactionType !== undefined) {
|
|
2078
|
+
request['type'] = transactionType;
|
|
2079
|
+
}
|
|
2080
|
+
const response = await this.v1PrivateGetAssetHistory(this.extend(request, params));
|
|
2081
|
+
//
|
|
2082
|
+
// {
|
|
2083
|
+
// "success": true,
|
|
2084
|
+
// "timestamp": 1702989203989,
|
|
2085
|
+
// "data": {
|
|
2086
|
+
// "meta": {
|
|
2087
|
+
// "total": 9,
|
|
2088
|
+
// "records_per_page": 25,
|
|
2089
|
+
// "current_page": 1
|
|
2090
|
+
// },
|
|
2091
|
+
// "rows": [{
|
|
2092
|
+
// "id": "230707030600002",
|
|
2093
|
+
// "tx_id": "0x4b0714c63cc7abae72bf68e84e25860b88ca651b7d27dad1e32bf4c027fa5326",
|
|
2094
|
+
// "side": "WITHDRAW",
|
|
2095
|
+
// "token": "USDC",
|
|
2096
|
+
// "amount": 555,
|
|
2097
|
+
// "fee": 123,
|
|
2098
|
+
// "trans_status": "FAILED",
|
|
2099
|
+
// "created_time": 1688699193034,
|
|
2100
|
+
// "updated_time": 1688699193096,
|
|
2101
|
+
// "chain_id": "986532"
|
|
2102
|
+
// }]
|
|
2103
|
+
// }
|
|
2104
|
+
// }
|
|
2105
|
+
//
|
|
2106
|
+
const data = this.safeDict(response, 'data', {});
|
|
2107
|
+
return [currency, this.safeList(data, 'rows', [])];
|
|
2108
|
+
}
|
|
2109
|
+
parseLedgerEntry(item, currency = undefined) {
|
|
2110
|
+
const code = this.safeString(item, 'token');
|
|
2111
|
+
const amount = this.safeNumber(item, 'amount');
|
|
2112
|
+
const side = this.safeString(item, 'token_side');
|
|
2113
|
+
const direction = (side === 'DEPOSIT') ? 'in' : 'out';
|
|
2114
|
+
const timestamp = this.safeInteger(item, 'created_time');
|
|
2115
|
+
const fee = this.parseTokenAndFeeTemp(item, 'fee_token', 'fee_amount');
|
|
2116
|
+
return {
|
|
2117
|
+
'id': this.safeString(item, 'id'),
|
|
2118
|
+
'currency': code,
|
|
2119
|
+
'account': this.safeString(item, 'account'),
|
|
2120
|
+
'referenceAccount': undefined,
|
|
2121
|
+
'referenceId': this.safeString(item, 'tx_id'),
|
|
2122
|
+
'status': this.parseTransactionStatus(this.safeString(item, 'status')),
|
|
2123
|
+
'amount': amount,
|
|
2124
|
+
'before': undefined,
|
|
2125
|
+
'after': undefined,
|
|
2126
|
+
'fee': fee,
|
|
2127
|
+
'direction': direction,
|
|
2128
|
+
'timestamp': timestamp,
|
|
2129
|
+
'datetime': this.iso8601(timestamp),
|
|
2130
|
+
'type': this.parseLedgerEntryType(this.safeString(item, 'type')),
|
|
2131
|
+
'info': item,
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
parseLedgerEntryType(type) {
|
|
2135
|
+
const types = {
|
|
2136
|
+
'BALANCE': 'transaction',
|
|
2137
|
+
'COLLATERAL': 'transfer', // Funds moved between portfolios
|
|
2138
|
+
};
|
|
2139
|
+
return this.safeString(types, type, type);
|
|
2140
|
+
}
|
|
2141
|
+
async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2142
|
+
/**
|
|
2143
|
+
* @method
|
|
2144
|
+
* @name woofipro#fetchLedger
|
|
2145
|
+
* @description fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
2146
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
|
|
2147
|
+
* @param {string} code unified currency code, default is undefined
|
|
2148
|
+
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
|
2149
|
+
* @param {int} [limit] max number of ledger entrys to return, default is undefined
|
|
2150
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2151
|
+
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
|
|
2152
|
+
*/
|
|
2153
|
+
const [currency, rows] = await this.getAssetHistoryRows(code, since, limit, params);
|
|
2154
|
+
return this.parseLedger(rows, currency, since, limit, params);
|
|
2155
|
+
}
|
|
2156
|
+
parseTransaction(transaction, currency = undefined) {
|
|
2157
|
+
// example in fetchLedger
|
|
2158
|
+
const code = this.safeString(transaction, 'token');
|
|
2159
|
+
let movementDirection = this.safeStringLower(transaction, 'token_side');
|
|
2160
|
+
if (movementDirection === 'withdraw') {
|
|
2161
|
+
movementDirection = 'withdrawal';
|
|
2162
|
+
}
|
|
2163
|
+
const fee = this.parseTokenAndFeeTemp(transaction, 'fee_token', 'fee_amount');
|
|
2164
|
+
const addressTo = this.safeString(transaction, 'target_address');
|
|
2165
|
+
const addressFrom = this.safeString(transaction, 'source_address');
|
|
2166
|
+
const timestamp = this.safeInteger(transaction, 'created_time');
|
|
2167
|
+
return {
|
|
2168
|
+
'info': transaction,
|
|
2169
|
+
'id': this.safeString2(transaction, 'id', 'withdraw_id'),
|
|
2170
|
+
'txid': this.safeString(transaction, 'tx_id'),
|
|
2171
|
+
'timestamp': timestamp,
|
|
2172
|
+
'datetime': this.iso8601(timestamp),
|
|
2173
|
+
'address': undefined,
|
|
2174
|
+
'addressFrom': addressFrom,
|
|
2175
|
+
'addressTo': addressTo,
|
|
2176
|
+
'tag': this.safeString(transaction, 'extra'),
|
|
2177
|
+
'tagFrom': undefined,
|
|
2178
|
+
'tagTo': undefined,
|
|
2179
|
+
'type': movementDirection,
|
|
2180
|
+
'amount': this.safeNumber(transaction, 'amount'),
|
|
2181
|
+
'currency': code,
|
|
2182
|
+
'status': this.parseTransactionStatus(this.safeString(transaction, 'status')),
|
|
2183
|
+
'updated': this.safeInteger(transaction, 'updated_time'),
|
|
2184
|
+
'comment': undefined,
|
|
2185
|
+
'internal': undefined,
|
|
2186
|
+
'fee': fee,
|
|
2187
|
+
'network': undefined,
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
parseTransactionStatus(status) {
|
|
2191
|
+
const statuses = {
|
|
2192
|
+
'NEW': 'pending',
|
|
2193
|
+
'CONFIRMING': 'pending',
|
|
2194
|
+
'PROCESSING': 'pending',
|
|
2195
|
+
'COMPLETED': 'ok',
|
|
2196
|
+
'CANCELED': 'canceled',
|
|
2197
|
+
};
|
|
2198
|
+
return this.safeString(statuses, status, status);
|
|
2199
|
+
}
|
|
2200
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2201
|
+
/**
|
|
2202
|
+
* @method
|
|
2203
|
+
* @name woofipro#fetchDeposits
|
|
2204
|
+
* @description fetch all deposits made to an account
|
|
2205
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
|
|
2206
|
+
* @param {string} code unified currency code
|
|
2207
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
2208
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
2209
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2210
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2211
|
+
*/
|
|
2212
|
+
const request = {
|
|
2213
|
+
'side': 'DEPOSIT',
|
|
2214
|
+
};
|
|
2215
|
+
return await this.fetchDepositsWithdrawals(code, since, limit, this.extend(request, params));
|
|
2216
|
+
}
|
|
2217
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2218
|
+
/**
|
|
2219
|
+
* @method
|
|
2220
|
+
* @name woofipro#fetchWithdrawals
|
|
2221
|
+
* @description fetch all withdrawals made from an account
|
|
2222
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
|
|
2223
|
+
* @param {string} code unified currency code
|
|
2224
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
2225
|
+
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
2226
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2227
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2228
|
+
*/
|
|
2229
|
+
const request = {
|
|
2230
|
+
'side': 'WITHDRAW',
|
|
2231
|
+
};
|
|
2232
|
+
return await this.fetchDepositsWithdrawals(code, since, limit, this.extend(request, params));
|
|
2233
|
+
}
|
|
2234
|
+
async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2235
|
+
/**
|
|
2236
|
+
* @method
|
|
2237
|
+
* @name woofipro#fetchDepositsWithdrawals
|
|
2238
|
+
* @description fetch history of deposits and withdrawals
|
|
2239
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-asset-history
|
|
2240
|
+
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
|
2241
|
+
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
|
2242
|
+
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
|
2243
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2244
|
+
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2245
|
+
*/
|
|
2246
|
+
const request = {};
|
|
2247
|
+
const [currency, rows] = await this.getAssetHistoryRows(code, since, limit, this.extend(request, params));
|
|
2248
|
+
//
|
|
2249
|
+
// {
|
|
2250
|
+
// "rows":[],
|
|
2251
|
+
// "meta":{
|
|
2252
|
+
// "total":0,
|
|
2253
|
+
// "records_per_page":25,
|
|
2254
|
+
// "current_page":1
|
|
2255
|
+
// },
|
|
2256
|
+
// "success":true
|
|
2257
|
+
// }
|
|
2258
|
+
//
|
|
2259
|
+
return this.parseTransactions(rows, currency, since, limit, params);
|
|
2260
|
+
}
|
|
2261
|
+
async getWithdrawNonce(params = {}) {
|
|
2262
|
+
const response = await this.v1PrivateGetWithdrawNonce(params);
|
|
2263
|
+
//
|
|
2264
|
+
// {
|
|
2265
|
+
// "success": true,
|
|
2266
|
+
// "timestamp": 1702989203989,
|
|
2267
|
+
// "data": {
|
|
2268
|
+
// "withdraw_nonce": 1
|
|
2269
|
+
// }
|
|
2270
|
+
// }
|
|
2271
|
+
//
|
|
2272
|
+
const data = this.safeDict(response, 'data', {});
|
|
2273
|
+
return this.safeNumber(data, 'withdraw_nonce');
|
|
2274
|
+
}
|
|
2275
|
+
hashMessage(message) {
|
|
2276
|
+
return '0x' + this.hash(message, sha3.keccak_256, 'hex');
|
|
2277
|
+
}
|
|
2278
|
+
signHash(hash, privateKey) {
|
|
2279
|
+
const signature = crypto.ecdsa(hash.slice(-64), privateKey.slice(-64), secp256k1.secp256k1, undefined);
|
|
2280
|
+
const v = this.intToBase16(this.sum(27, signature['v']));
|
|
2281
|
+
return '0x' + signature['r'].padStart(64, '0') + signature['s'].padStart(64, '0') + v;
|
|
2282
|
+
}
|
|
2283
|
+
signMessage(message, privateKey) {
|
|
2284
|
+
return this.signHash(this.hashMessage(message), privateKey.slice(-64));
|
|
2285
|
+
}
|
|
2286
|
+
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
2287
|
+
/**
|
|
2288
|
+
* @method
|
|
2289
|
+
* @name woofipro#withdraw
|
|
2290
|
+
* @description make a withdrawal
|
|
2291
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/create-withdraw-request
|
|
2292
|
+
* @param {string} code unified currency code
|
|
2293
|
+
* @param {float} amount the amount to withdraw
|
|
2294
|
+
* @param {string} address the address to withdraw to
|
|
2295
|
+
* @param {string} tag
|
|
2296
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2297
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
2298
|
+
*/
|
|
2299
|
+
await this.loadMarkets();
|
|
2300
|
+
this.checkAddress(address);
|
|
2301
|
+
if (code !== undefined) {
|
|
2302
|
+
code = code.toUpperCase();
|
|
2303
|
+
if (code !== 'USDC') {
|
|
2304
|
+
throw new errors.NotSupported(this.id + 'withdraw() only support USDC');
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
const currency = this.currency(code);
|
|
2308
|
+
const verifyingContractAddress = this.safeString(this.options, 'verifyingContractAddress');
|
|
2309
|
+
const chainId = this.safeString(params, 'chainId');
|
|
2310
|
+
const currencyNetworks = this.safeDict(currency, 'networks', {});
|
|
2311
|
+
const coinNetwork = this.safeDict(currencyNetworks, chainId, {});
|
|
2312
|
+
const coinNetworkId = this.safeNumber(coinNetwork, 'id');
|
|
2313
|
+
if (coinNetworkId === undefined) {
|
|
2314
|
+
throw new errors.BadRequest(this.id + ' withdraw() require chainId parameter');
|
|
2315
|
+
}
|
|
2316
|
+
const withdrawNonce = await this.getWithdrawNonce(params);
|
|
2317
|
+
const nonce = this.nonce();
|
|
2318
|
+
const domain = {
|
|
2319
|
+
'chainId': chainId,
|
|
2320
|
+
'name': 'Orderly',
|
|
2321
|
+
'verifyingContract': verifyingContractAddress,
|
|
2322
|
+
'version': '1',
|
|
2323
|
+
};
|
|
2324
|
+
const messageTypes = {
|
|
2325
|
+
'Withdraw': [
|
|
2326
|
+
{ 'name': 'brokerId', 'type': 'string' },
|
|
2327
|
+
{ 'name': 'chainId', 'type': 'uint256' },
|
|
2328
|
+
{ 'name': 'receiver', 'type': 'address' },
|
|
2329
|
+
{ 'name': 'token', 'type': 'string' },
|
|
2330
|
+
{ 'name': 'amount', 'type': 'uint256' },
|
|
2331
|
+
{ 'name': 'withdrawNonce', 'type': 'uint64' },
|
|
2332
|
+
{ 'name': 'timestamp', 'type': 'uint64' },
|
|
2333
|
+
],
|
|
2334
|
+
};
|
|
2335
|
+
const withdrawRequest = {
|
|
2336
|
+
'brokerId': this.safeString(this.options, 'keyBrokerId', 'woofi_pro'),
|
|
2337
|
+
'chainId': this.parseToInt(chainId),
|
|
2338
|
+
'receiver': address,
|
|
2339
|
+
'token': code,
|
|
2340
|
+
'amount': amount.toString(),
|
|
2341
|
+
'withdrawNonce': withdrawNonce,
|
|
2342
|
+
'timestamp': nonce,
|
|
2343
|
+
};
|
|
2344
|
+
const msg = this.ethEncodeStructuredData(domain, messageTypes, withdrawRequest);
|
|
2345
|
+
const signature = this.signMessage(msg, this.privateKey);
|
|
2346
|
+
const request = {
|
|
2347
|
+
'signature': signature,
|
|
2348
|
+
'userAddress': address,
|
|
2349
|
+
'verifyingContract': verifyingContractAddress,
|
|
2350
|
+
'message': withdrawRequest,
|
|
2351
|
+
};
|
|
2352
|
+
params = this.omit(params, 'chainId');
|
|
2353
|
+
const response = await this.v1PrivatePostWithdrawRequest(this.extend(request, params));
|
|
2354
|
+
//
|
|
2355
|
+
// {
|
|
2356
|
+
// "success": true,
|
|
2357
|
+
// "timestamp": 1702989203989,
|
|
2358
|
+
// "data": {
|
|
2359
|
+
// "withdraw_id": 123
|
|
2360
|
+
// }
|
|
2361
|
+
// }
|
|
2362
|
+
//
|
|
2363
|
+
const data = this.safeDict(response, 'data', {});
|
|
2364
|
+
return this.parseTransaction(data, currency);
|
|
2365
|
+
}
|
|
2366
|
+
parseLeverage(leverage, market = undefined) {
|
|
2367
|
+
const leverageValue = this.safeInteger(leverage, 'max_leverage');
|
|
2368
|
+
return {
|
|
2369
|
+
'info': leverage,
|
|
2370
|
+
'symbol': market['symbol'],
|
|
2371
|
+
'marginMode': undefined,
|
|
2372
|
+
'longLeverage': leverageValue,
|
|
2373
|
+
'shortLeverage': leverageValue,
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2376
|
+
async fetchLeverage(symbol, params = {}) {
|
|
2377
|
+
/**
|
|
2378
|
+
* @method
|
|
2379
|
+
* @name woofipro#fetchLeverage
|
|
2380
|
+
* @description fetch the set leverage for a market
|
|
2381
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-account-information
|
|
2382
|
+
* @param {string} symbol unified market symbol
|
|
2383
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2384
|
+
* @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
|
|
2385
|
+
*/
|
|
2386
|
+
await this.loadMarkets();
|
|
2387
|
+
const market = this.market(symbol);
|
|
2388
|
+
const response = await this.v1PrivateGetClientInfo(params);
|
|
2389
|
+
//
|
|
2390
|
+
// {
|
|
2391
|
+
// "success": true,
|
|
2392
|
+
// "timestamp": 1702989203989,
|
|
2393
|
+
// "data": {
|
|
2394
|
+
// "account_id": "<string>",
|
|
2395
|
+
// "email": "test@test.com",
|
|
2396
|
+
// "account_mode": "FUTURES",
|
|
2397
|
+
// "max_leverage": 20,
|
|
2398
|
+
// "taker_fee_rate": 123,
|
|
2399
|
+
// "maker_fee_rate": 123,
|
|
2400
|
+
// "futures_taker_fee_rate": 123,
|
|
2401
|
+
// "futures_maker_fee_rate": 123,
|
|
2402
|
+
// "maintenance_cancel_orders": true,
|
|
2403
|
+
// "imr_factor": {
|
|
2404
|
+
// "PERP_BTC_USDC": 123,
|
|
2405
|
+
// "PERP_ETH_USDC": 123,
|
|
2406
|
+
// "PERP_NEAR_USDC": 123
|
|
2407
|
+
// },
|
|
2408
|
+
// "max_notional": {
|
|
2409
|
+
// "PERP_BTC_USDC": 123,
|
|
2410
|
+
// "PERP_ETH_USDC": 123,
|
|
2411
|
+
// "PERP_NEAR_USDC": 123
|
|
2412
|
+
// }
|
|
2413
|
+
// }
|
|
2414
|
+
// }
|
|
2415
|
+
//
|
|
2416
|
+
const data = this.safeDict(response, 'data', {});
|
|
2417
|
+
return this.parseLeverage(data, market);
|
|
2418
|
+
}
|
|
2419
|
+
async setLeverage(leverage, symbol = undefined, params = {}) {
|
|
2420
|
+
/**
|
|
2421
|
+
* @method
|
|
2422
|
+
* @name woofipro#setLeverage
|
|
2423
|
+
* @description set the level of leverage for a market
|
|
2424
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/update-leverage-setting
|
|
2425
|
+
* @param {string} symbol unified market symbol
|
|
2426
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2427
|
+
* @returns {object} response from the exchange
|
|
2428
|
+
*/
|
|
2429
|
+
await this.loadMarkets();
|
|
2430
|
+
if ((leverage < 1) || (leverage > 50)) {
|
|
2431
|
+
throw new errors.BadRequest(this.id + ' leverage should be between 1 and 50');
|
|
2432
|
+
}
|
|
2433
|
+
const request = {
|
|
2434
|
+
'leverage': leverage,
|
|
2435
|
+
};
|
|
2436
|
+
return await this.v1PrivatePostClientLeverage(this.extend(request, params));
|
|
2437
|
+
}
|
|
2438
|
+
parsePosition(position, market = undefined) {
|
|
2439
|
+
//
|
|
2440
|
+
// {
|
|
2441
|
+
// "IMR_withdraw_orders": 0.1,
|
|
2442
|
+
// "MMR_with_orders": 0.05,
|
|
2443
|
+
// "average_open_price": 27908.14386047,
|
|
2444
|
+
// "cost_position": -139329.358492,
|
|
2445
|
+
// "est_liq_price": 117335.92899428,
|
|
2446
|
+
// "fee_24_h": 123,
|
|
2447
|
+
// "imr": 0.1,
|
|
2448
|
+
// "last_sum_unitary_funding": 70.38,
|
|
2449
|
+
// "mark_price": 27794.9,
|
|
2450
|
+
// "mmr": 0.05,
|
|
2451
|
+
// "pending_long_qty": 123,
|
|
2452
|
+
// "pending_short_qty": 123,
|
|
2453
|
+
// "pnl_24_h": 123,
|
|
2454
|
+
// "position_qty": -5,
|
|
2455
|
+
// "settle_price": 27865.8716984,
|
|
2456
|
+
// "symbol": "PERP_BTC_USDC",
|
|
2457
|
+
// "timestamp": 1685429350571,
|
|
2458
|
+
// "unsettled_pnl": 354.858492
|
|
2459
|
+
// }
|
|
2460
|
+
//
|
|
2461
|
+
const contract = this.safeString(position, 'symbol');
|
|
2462
|
+
market = this.safeMarket(contract, market);
|
|
2463
|
+
let size = this.safeString(position, 'position_qty');
|
|
2464
|
+
let side = undefined;
|
|
2465
|
+
if (Precise["default"].stringGt(size, '0')) {
|
|
2466
|
+
side = 'long';
|
|
2467
|
+
}
|
|
2468
|
+
else {
|
|
2469
|
+
side = 'short';
|
|
2470
|
+
}
|
|
2471
|
+
const contractSize = this.safeString(market, 'contractSize');
|
|
2472
|
+
const markPrice = this.safeString(position, 'mark_price');
|
|
2473
|
+
const timestamp = this.safeInteger(position, 'timestamp');
|
|
2474
|
+
const entryPrice = this.safeString(position, 'average_open_price');
|
|
2475
|
+
const unrealisedPnl = this.safeString(position, 'unsettled_pnl');
|
|
2476
|
+
size = Precise["default"].stringAbs(size);
|
|
2477
|
+
const notional = Precise["default"].stringMul(size, markPrice);
|
|
2478
|
+
return this.safePosition({
|
|
2479
|
+
'info': position,
|
|
2480
|
+
'id': undefined,
|
|
2481
|
+
'symbol': this.safeString(market, 'symbol'),
|
|
2482
|
+
'timestamp': timestamp,
|
|
2483
|
+
'datetime': this.iso8601(timestamp),
|
|
2484
|
+
'lastUpdateTimestamp': undefined,
|
|
2485
|
+
'initialMargin': undefined,
|
|
2486
|
+
'initialMarginPercentage': undefined,
|
|
2487
|
+
'maintenanceMargin': undefined,
|
|
2488
|
+
'maintenanceMarginPercentage': undefined,
|
|
2489
|
+
'entryPrice': this.parseNumber(entryPrice),
|
|
2490
|
+
'notional': this.parseNumber(notional),
|
|
2491
|
+
'leverage': undefined,
|
|
2492
|
+
'unrealizedPnl': this.parseNumber(unrealisedPnl),
|
|
2493
|
+
'contracts': this.parseNumber(size),
|
|
2494
|
+
'contractSize': this.parseNumber(contractSize),
|
|
2495
|
+
'marginRatio': undefined,
|
|
2496
|
+
'liquidationPrice': this.safeNumber(position, 'est_liq_price'),
|
|
2497
|
+
'markPrice': this.parseNumber(markPrice),
|
|
2498
|
+
'lastPrice': undefined,
|
|
2499
|
+
'collateral': undefined,
|
|
2500
|
+
'marginMode': 'cross',
|
|
2501
|
+
'marginType': undefined,
|
|
2502
|
+
'side': side,
|
|
2503
|
+
'percentage': undefined,
|
|
2504
|
+
'hedged': undefined,
|
|
2505
|
+
'stopLossPrice': undefined,
|
|
2506
|
+
'takeProfitPrice': undefined,
|
|
2507
|
+
});
|
|
2508
|
+
}
|
|
2509
|
+
async fetchPosition(symbol = undefined, params = {}) {
|
|
2510
|
+
/**
|
|
2511
|
+
* @method
|
|
2512
|
+
* @name woofipro#fetchPosition
|
|
2513
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-one-position-info
|
|
2514
|
+
* @description fetch data on an open position
|
|
2515
|
+
* @param {string} symbol unified market symbol of the market the position is held in
|
|
2516
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2517
|
+
* @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2518
|
+
*/
|
|
2519
|
+
await this.loadMarkets();
|
|
2520
|
+
const market = this.market(symbol);
|
|
2521
|
+
const request = {
|
|
2522
|
+
'symbol': market['id'],
|
|
2523
|
+
};
|
|
2524
|
+
const response = await this.v1PrivateGetPositionSymbol(this.extend(request, params));
|
|
2525
|
+
//
|
|
2526
|
+
// {
|
|
2527
|
+
// "success": true,
|
|
2528
|
+
// "timestamp": 1702989203989,
|
|
2529
|
+
// "data": {
|
|
2530
|
+
// "IMR_withdraw_orders": 0.1,
|
|
2531
|
+
// "MMR_with_orders": 0.05,
|
|
2532
|
+
// "average_open_price": 27908.14386047,
|
|
2533
|
+
// "cost_position": -139329.358492,
|
|
2534
|
+
// "est_liq_price": 117335.92899428,
|
|
2535
|
+
// "fee_24_h": 123,
|
|
2536
|
+
// "imr": 0.1,
|
|
2537
|
+
// "last_sum_unitary_funding": 70.38,
|
|
2538
|
+
// "mark_price": 27794.9,
|
|
2539
|
+
// "mmr": 0.05,
|
|
2540
|
+
// "pending_long_qty": 123,
|
|
2541
|
+
// "pending_short_qty": 123,
|
|
2542
|
+
// "pnl_24_h": 123,
|
|
2543
|
+
// "position_qty": -5,
|
|
2544
|
+
// "settle_price": 27865.8716984,
|
|
2545
|
+
// "symbol": "PERP_BTC_USDC",
|
|
2546
|
+
// "timestamp": 1685429350571,
|
|
2547
|
+
// "unsettled_pnl": 354.858492
|
|
2548
|
+
// }
|
|
2549
|
+
// }
|
|
2550
|
+
//
|
|
2551
|
+
const data = this.safeDict(response, 'data');
|
|
2552
|
+
return this.parsePosition(data, market);
|
|
2553
|
+
}
|
|
2554
|
+
async fetchPositions(symbols = undefined, params = {}) {
|
|
2555
|
+
/**
|
|
2556
|
+
* @method
|
|
2557
|
+
* @name woofipro#fetchPositions
|
|
2558
|
+
* @description fetch all open positions
|
|
2559
|
+
* @see https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/get-all-positions-info
|
|
2560
|
+
* @param {string[]} [symbols] list of unified market symbols
|
|
2561
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2562
|
+
* @param {string} [method] method name to call, "positionRisk", "account" or "option", default is "positionRisk"
|
|
2563
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
|
2564
|
+
*/
|
|
2565
|
+
await this.loadMarkets();
|
|
2566
|
+
const response = await this.v1PrivateGetPositions(params);
|
|
2567
|
+
//
|
|
2568
|
+
// {
|
|
2569
|
+
// "success": true,
|
|
2570
|
+
// "timestamp": 1702989203989,
|
|
2571
|
+
// "data": {
|
|
2572
|
+
// "current_margin_ratio_with_orders": 1.2385,
|
|
2573
|
+
// "free_collateral": 450315.09115,
|
|
2574
|
+
// "initial_margin_ratio": 0.1,
|
|
2575
|
+
// "initial_margin_ratio_with_orders": 0.1,
|
|
2576
|
+
// "maintenance_margin_ratio": 0.05,
|
|
2577
|
+
// "maintenance_margin_ratio_with_orders": 0.05,
|
|
2578
|
+
// "margin_ratio": 1.2385,
|
|
2579
|
+
// "open_margin_ratio": 1.2102,
|
|
2580
|
+
// "total_collateral_value": 489865.71329,
|
|
2581
|
+
// "total_pnl_24_h": 123,
|
|
2582
|
+
// "rows": [{
|
|
2583
|
+
// "IMR_withdraw_orders": 0.1,
|
|
2584
|
+
// "MMR_with_orders": 0.05,
|
|
2585
|
+
// "average_open_price": 27908.14386047,
|
|
2586
|
+
// "cost_position": -139329.358492,
|
|
2587
|
+
// "est_liq_price": 117335.92899428,
|
|
2588
|
+
// "fee_24_h": 123,
|
|
2589
|
+
// "imr": 0.1,
|
|
2590
|
+
// "last_sum_unitary_funding": 70.38,
|
|
2591
|
+
// "mark_price": 27794.9,
|
|
2592
|
+
// "mmr": 0.05,
|
|
2593
|
+
// "pending_long_qty": 123,
|
|
2594
|
+
// "pending_short_qty": 123,
|
|
2595
|
+
// "pnl_24_h": 123,
|
|
2596
|
+
// "position_qty": -5,
|
|
2597
|
+
// "settle_price": 27865.8716984,
|
|
2598
|
+
// "symbol": "PERP_BTC_USDC",
|
|
2599
|
+
// "timestamp": 1685429350571,
|
|
2600
|
+
// "unsettled_pnl": 354.858492
|
|
2601
|
+
// }]
|
|
2602
|
+
// }
|
|
2603
|
+
// }
|
|
2604
|
+
//
|
|
2605
|
+
const result = this.safeDict(response, 'data', {});
|
|
2606
|
+
const positions = this.safeList(result, 'rows', []);
|
|
2607
|
+
return this.parsePositions(positions, symbols);
|
|
2608
|
+
}
|
|
2609
|
+
nonce() {
|
|
2610
|
+
return this.milliseconds();
|
|
2611
|
+
}
|
|
2612
|
+
sign(path, section = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2613
|
+
const version = section[0];
|
|
2614
|
+
const access = section[1];
|
|
2615
|
+
const pathWithParams = this.implodeParams(path, params);
|
|
2616
|
+
let url = this.implodeHostname(this.urls['api'][access]);
|
|
2617
|
+
url += '/' + version + '/';
|
|
2618
|
+
params = this.omit(params, this.extractParams(path));
|
|
2619
|
+
params = this.keysort(params);
|
|
2620
|
+
if (access === 'public') {
|
|
2621
|
+
url += pathWithParams;
|
|
2622
|
+
if (Object.keys(params).length) {
|
|
2623
|
+
url += '?' + this.urlencode(params);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
else {
|
|
2627
|
+
this.checkRequiredCredentials();
|
|
2628
|
+
if ((method === 'POST' || method === 'PUT') && (path === 'algo/order' || path === 'order' || path === 'batch-order')) {
|
|
2629
|
+
const isSandboxMode = this.safeBool(this.options, 'sandboxMode', false);
|
|
2630
|
+
if (!isSandboxMode) {
|
|
2631
|
+
const brokerId = this.safeString(this.options, 'brokerId', 'CCXT');
|
|
2632
|
+
if (path === 'batch-order') {
|
|
2633
|
+
const ordersList = this.safeList(params, 'orders', []);
|
|
2634
|
+
for (let i = 0; i < ordersList.length; i++) {
|
|
2635
|
+
params['orders'][i]['order_tag'] = brokerId;
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
else {
|
|
2639
|
+
params['order_tag'] = brokerId;
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
params = this.keysort(params);
|
|
2643
|
+
}
|
|
2644
|
+
let auth = '';
|
|
2645
|
+
const ts = this.nonce().toString();
|
|
2646
|
+
url += pathWithParams;
|
|
2647
|
+
headers = {
|
|
2648
|
+
'orderly-account-id': this.accountId,
|
|
2649
|
+
'orderly-key': this.apiKey,
|
|
2650
|
+
'orderly-timestamp': ts,
|
|
2651
|
+
};
|
|
2652
|
+
auth = ts + method + '/' + version + '/' + pathWithParams;
|
|
2653
|
+
if (method === 'POST' || method === 'PUT') {
|
|
2654
|
+
body = this.json(params);
|
|
2655
|
+
auth += body;
|
|
2656
|
+
headers['content-type'] = 'application/json';
|
|
2657
|
+
}
|
|
2658
|
+
else {
|
|
2659
|
+
if (Object.keys(params).length) {
|
|
2660
|
+
url += '?' + this.urlencode(params);
|
|
2661
|
+
auth += '?' + this.rawencode(params);
|
|
2662
|
+
}
|
|
2663
|
+
headers['content-type'] = 'application/x-www-form-urlencoded';
|
|
2664
|
+
if (method === 'DELETE') {
|
|
2665
|
+
body = '';
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
let secret = this.secret;
|
|
2669
|
+
if (secret.indexOf('ed25519:') >= 0) {
|
|
2670
|
+
const parts = secret.split('ed25519:');
|
|
2671
|
+
secret = parts[1];
|
|
2672
|
+
}
|
|
2673
|
+
const signature = crypto.eddsa(this.encode(auth), this.base58ToBinary(secret), ed25519.ed25519);
|
|
2674
|
+
headers['orderly-signature'] = this.urlencodeBase64(this.base64ToBinary(signature));
|
|
2675
|
+
}
|
|
2676
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2677
|
+
}
|
|
2678
|
+
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2679
|
+
if (!response) {
|
|
2680
|
+
return undefined; // fallback to default error handler
|
|
2681
|
+
}
|
|
2682
|
+
//
|
|
2683
|
+
// 400 Bad Request {"success":false,"code":-1012,"message":"Amount is required for buy market orders when margin disabled."}
|
|
2684
|
+
// {"code":"-1011","message":"The system is under maintenance.","success":false}
|
|
2685
|
+
//
|
|
2686
|
+
const success = this.safeBool(response, 'success');
|
|
2687
|
+
const errorCode = this.safeString(response, 'code');
|
|
2688
|
+
if (!success) {
|
|
2689
|
+
const feedback = this.id + ' ' + this.json(response);
|
|
2690
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], body, feedback);
|
|
2691
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
|
|
2692
|
+
throw new errors.ExchangeError(feedback);
|
|
2693
|
+
}
|
|
2694
|
+
return undefined;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
module.exports = woofipro;
|