ccxt 4.5.29 → 4.5.30
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 +6 -5
- package/dist/ccxt.browser.min.js +7 -7
- package/dist/cjs/ccxt.js +6 -1
- package/dist/cjs/src/abstract/bydfi.js +11 -0
- package/dist/cjs/src/bingx.js +1 -1
- package/dist/cjs/src/bullish.js +1 -1
- package/dist/cjs/src/bybit.js +2 -0
- package/dist/cjs/src/bydfi.js +2907 -0
- package/dist/cjs/src/coinbase.js +34 -1
- package/dist/cjs/src/dydx.js +3 -3
- package/dist/cjs/src/gate.js +3 -2
- package/dist/cjs/src/hyperliquid.js +10 -3
- package/dist/cjs/src/kucoin.js +112 -4
- package/dist/cjs/src/pro/apex.js +5 -3
- package/dist/cjs/src/pro/binance.js +10 -6
- package/dist/cjs/src/pro/bingx.js +5 -3
- package/dist/cjs/src/pro/bitmart.js +5 -3
- package/dist/cjs/src/pro/bybit.js +5 -3
- package/dist/cjs/src/pro/bydfi.js +1077 -0
- package/dist/cjs/src/pro/cryptocom.js +5 -3
- package/dist/cjs/src/pro/gate.js +5 -3
- package/dist/cjs/src/pro/hashkey.js +5 -3
- package/dist/cjs/src/pro/kucoinfutures.js +5 -3
- package/dist/cjs/src/pro/modetrade.js +5 -3
- package/dist/cjs/src/pro/toobit.js +11 -7
- package/dist/cjs/src/pro/woo.js +5 -3
- package/dist/cjs/src/pro/woofipro.js +5 -3
- package/dist/cjs/src/pro/xt.js +5 -3
- package/dist/cjs/src/toobit.js +2 -1
- package/js/ccxt.d.ts +8 -2
- package/js/ccxt.js +6 -2
- package/js/src/abstract/bydfi.d.ts +52 -0
- package/js/src/abstract/bydfi.js +11 -0
- package/js/src/bingx.js +1 -1
- package/js/src/bullish.js +1 -1
- package/js/src/bybit.js +2 -0
- package/js/src/bydfi.d.ts +472 -0
- package/js/src/bydfi.js +2905 -0
- package/js/src/coinbase.d.ts +11 -0
- package/js/src/coinbase.js +34 -1
- package/js/src/dydx.js +3 -3
- package/js/src/gate.js +3 -2
- package/js/src/hyperliquid.js +10 -3
- package/js/src/kucoin.d.ts +14 -0
- package/js/src/kucoin.js +112 -4
- package/js/src/pro/apex.js +5 -3
- package/js/src/pro/binance.js +10 -6
- package/js/src/pro/bingx.js +5 -3
- package/js/src/pro/bitmart.js +5 -3
- package/js/src/pro/bybit.js +5 -3
- package/js/src/pro/bydfi.d.ts +206 -0
- package/js/src/pro/bydfi.js +1076 -0
- package/js/src/pro/cryptocom.js +5 -3
- package/js/src/pro/gate.js +5 -3
- package/js/src/pro/hashkey.js +5 -3
- package/js/src/pro/kucoinfutures.js +5 -3
- package/js/src/pro/modetrade.js +5 -3
- package/js/src/pro/toobit.js +11 -7
- package/js/src/pro/woo.js +5 -3
- package/js/src/pro/woofipro.js +5 -3
- package/js/src/pro/xt.js +5 -3
- package/js/src/toobit.js +2 -1
- package/package.json +1 -1
package/js/src/bydfi.js
ADDED
|
@@ -0,0 +1,2905 @@
|
|
|
1
|
+
// ----------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
+
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
+
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
import Exchange from './abstract/bydfi.js';
|
|
9
|
+
import { ArgumentsRequired, AuthenticationError, BadRequest, ExchangeError, InsufficientFunds, NotSupported, PermissionDenied, RateLimitExceeded } from '../ccxt.js';
|
|
10
|
+
import { Precise } from './base/Precise.js';
|
|
11
|
+
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
|
|
12
|
+
import { TICK_SIZE } from './base/functions/number.js';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* @class bydfi
|
|
16
|
+
* @augments Exchange
|
|
17
|
+
*/
|
|
18
|
+
export default class bydfi extends Exchange {
|
|
19
|
+
describe() {
|
|
20
|
+
return this.deepExtend(super.describe(), {
|
|
21
|
+
'id': 'bydfi',
|
|
22
|
+
'name': 'BYDFi',
|
|
23
|
+
'countries': ['SG'],
|
|
24
|
+
'rateLimit': 50,
|
|
25
|
+
'version': 'v1',
|
|
26
|
+
'certified': false,
|
|
27
|
+
'pro': true,
|
|
28
|
+
'has': {
|
|
29
|
+
'CORS': undefined,
|
|
30
|
+
'spot': false,
|
|
31
|
+
'margin': false,
|
|
32
|
+
'swap': true,
|
|
33
|
+
'future': false,
|
|
34
|
+
'option': false,
|
|
35
|
+
'addMargin': false,
|
|
36
|
+
'borrowCrossMargin': false,
|
|
37
|
+
'borrowIsolatedMargin': false,
|
|
38
|
+
'borrowMargin': false,
|
|
39
|
+
'cancelAllOrders': true,
|
|
40
|
+
'cancelOrder': false,
|
|
41
|
+
'cancelOrders': false,
|
|
42
|
+
'cancelOrdersWithClientOrderId': false,
|
|
43
|
+
'cancelOrderWithClientOrderId': false,
|
|
44
|
+
'closeAllPositions': false,
|
|
45
|
+
'closePosition': false,
|
|
46
|
+
'createDepositAddress': false,
|
|
47
|
+
'createLimitBuyOrder': false,
|
|
48
|
+
'createLimitOrder': true,
|
|
49
|
+
'createLimitSellOrder': false,
|
|
50
|
+
'createMarketBuyOrder': false,
|
|
51
|
+
'createMarketBuyOrderWithCost': false,
|
|
52
|
+
'createMarketOrder': true,
|
|
53
|
+
'createMarketOrderWithCost': false,
|
|
54
|
+
'createMarketSellOrder': false,
|
|
55
|
+
'createMarketSellOrderWithCost': false,
|
|
56
|
+
'createOrder': true,
|
|
57
|
+
'createOrders': true,
|
|
58
|
+
'createOrderWithTakeProfitAndStopLoss': false,
|
|
59
|
+
'createPostOnlyOrder': true,
|
|
60
|
+
'createReduceOnlyOrder': true,
|
|
61
|
+
'createStopLimitOrder': true,
|
|
62
|
+
'createStopLossOrder': true,
|
|
63
|
+
'createStopMarketOrder': false,
|
|
64
|
+
'createStopOrder': false,
|
|
65
|
+
'createTakeProfitOrder': true,
|
|
66
|
+
'createTrailingAmountOrder': false,
|
|
67
|
+
'createTrailingPercentOrder': true,
|
|
68
|
+
'createTriggerOrder': false,
|
|
69
|
+
'deposit': false,
|
|
70
|
+
'editOrder': true,
|
|
71
|
+
'editOrders': true,
|
|
72
|
+
'editOrderWithClientOrderId': true,
|
|
73
|
+
'fetchAccounts': false,
|
|
74
|
+
'fetchBalance': true,
|
|
75
|
+
'fetchBidsAsks': false,
|
|
76
|
+
'fetchBorrowInterest': false,
|
|
77
|
+
'fetchBorrowRate': false,
|
|
78
|
+
'fetchBorrowRateHistories': false,
|
|
79
|
+
'fetchBorrowRateHistory': false,
|
|
80
|
+
'fetchBorrowRates': false,
|
|
81
|
+
'fetchBorrowRatesPerSymbol': false,
|
|
82
|
+
'fetchCanceledAndClosedOrders': true,
|
|
83
|
+
'fetchCanceledOrders': false,
|
|
84
|
+
'fetchClosedOrder': false,
|
|
85
|
+
'fetchClosedOrders': false,
|
|
86
|
+
'fetchConvertCurrencies': false,
|
|
87
|
+
'fetchConvertQuote': false,
|
|
88
|
+
'fetchConvertTrade': false,
|
|
89
|
+
'fetchConvertTradeHistory': false,
|
|
90
|
+
'fetchCrossBorrowRate': false,
|
|
91
|
+
'fetchCrossBorrowRates': false,
|
|
92
|
+
'fetchCurrencies': false,
|
|
93
|
+
'fetchDeposit': false,
|
|
94
|
+
'fetchDepositAddress': false,
|
|
95
|
+
'fetchDepositAddresses': false,
|
|
96
|
+
'fetchDepositAddressesByNetwork': false,
|
|
97
|
+
'fetchDeposits': true,
|
|
98
|
+
'fetchDepositsWithdrawals': false,
|
|
99
|
+
'fetchDepositWithdrawFee': false,
|
|
100
|
+
'fetchDepositWithdrawFees': false,
|
|
101
|
+
'fetchFundingHistory': false,
|
|
102
|
+
'fetchFundingInterval': false,
|
|
103
|
+
'fetchFundingIntervals': false,
|
|
104
|
+
'fetchFundingRate': true,
|
|
105
|
+
'fetchFundingRateHistory': true,
|
|
106
|
+
'fetchFundingRates': false,
|
|
107
|
+
'fetchGreeks': false,
|
|
108
|
+
'fetchIndexOHLCV': false,
|
|
109
|
+
'fetchIsolatedBorrowRate': false,
|
|
110
|
+
'fetchIsolatedBorrowRates': false,
|
|
111
|
+
'fetchIsolatedPositions': false,
|
|
112
|
+
'fetchL2OrderBook': true,
|
|
113
|
+
'fetchL3OrderBook': false,
|
|
114
|
+
'fetchLastPrices': false,
|
|
115
|
+
'fetchLedger': false,
|
|
116
|
+
'fetchLedgerEntry': false,
|
|
117
|
+
'fetchLeverage': true,
|
|
118
|
+
'fetchLeverages': false,
|
|
119
|
+
'fetchLeverageTiers': false,
|
|
120
|
+
'fetchLiquidations': false,
|
|
121
|
+
'fetchLongShortRatio': false,
|
|
122
|
+
'fetchLongShortRatioHistory': false,
|
|
123
|
+
'fetchMarginAdjustmentHistory': false,
|
|
124
|
+
'fetchMarginMode': true,
|
|
125
|
+
'fetchMarginModes': false,
|
|
126
|
+
'fetchMarketLeverageTiers': false,
|
|
127
|
+
'fetchMarkets': true,
|
|
128
|
+
'fetchMarkOHLCV': false,
|
|
129
|
+
'fetchMarkPrices': false,
|
|
130
|
+
'fetchMyLiquidations': false,
|
|
131
|
+
'fetchMySettlementHistory': false,
|
|
132
|
+
'fetchMyTrades': true,
|
|
133
|
+
'fetchOHLCV': true,
|
|
134
|
+
'fetchOpenInterest': false,
|
|
135
|
+
'fetchOpenInterestHistory': false,
|
|
136
|
+
'fetchOpenInterests': false,
|
|
137
|
+
'fetchOpenOrder': false,
|
|
138
|
+
'fetchOpenOrders': true,
|
|
139
|
+
'fetchOption': false,
|
|
140
|
+
'fetchOptionChain': false,
|
|
141
|
+
'fetchOrder': false,
|
|
142
|
+
'fetchOrderBook': true,
|
|
143
|
+
'fetchOrderBooks': false,
|
|
144
|
+
'fetchOrders': false,
|
|
145
|
+
'fetchOrdersByStatus': false,
|
|
146
|
+
'fetchOrderTrades': false,
|
|
147
|
+
'fetchOrderWithClientOrderId': false,
|
|
148
|
+
'fetchPosition': false,
|
|
149
|
+
'fetchPositionHistory': true,
|
|
150
|
+
'fetchPositionMode': true,
|
|
151
|
+
'fetchPositions': true,
|
|
152
|
+
'fetchPositionsForSymbol': true,
|
|
153
|
+
'fetchPositionsHistory': true,
|
|
154
|
+
'fetchPositionsRisk': false,
|
|
155
|
+
'fetchPremiumIndexOHLCV': false,
|
|
156
|
+
'fetchSettlementHistory': false,
|
|
157
|
+
'fetchStatus': false,
|
|
158
|
+
'fetchTicker': true,
|
|
159
|
+
'fetchTickers': true,
|
|
160
|
+
'fetchTime': false,
|
|
161
|
+
'fetchTrades': true,
|
|
162
|
+
'fetchTradingFee': false,
|
|
163
|
+
'fetchTradingFees': false,
|
|
164
|
+
'fetchTradingLimits': false,
|
|
165
|
+
'fetchTransactionFee': false,
|
|
166
|
+
'fetchTransactionFees': false,
|
|
167
|
+
'fetchTransactions': false,
|
|
168
|
+
'fetchTransfer': false,
|
|
169
|
+
'fetchTransfers': true,
|
|
170
|
+
'fetchUnderlyingAssets': false,
|
|
171
|
+
'fetchVolatilityHistory': false,
|
|
172
|
+
'fetchWithdrawAddresses': false,
|
|
173
|
+
'fetchWithdrawal': false,
|
|
174
|
+
'fetchWithdrawals': true,
|
|
175
|
+
'fetchWithdrawalWhitelist': false,
|
|
176
|
+
'reduceMargin': false,
|
|
177
|
+
'repayCrossMargin': false,
|
|
178
|
+
'repayIsolatedMargin': false,
|
|
179
|
+
'setLeverage': true,
|
|
180
|
+
'setMargin': false,
|
|
181
|
+
'setMarginMode': true,
|
|
182
|
+
'setPositionMode': true,
|
|
183
|
+
'signIn': false,
|
|
184
|
+
'transfer': true,
|
|
185
|
+
'watchMyLiquidationsForSymbols': false,
|
|
186
|
+
'withdraw': false,
|
|
187
|
+
'ws': true,
|
|
188
|
+
},
|
|
189
|
+
'urls': {
|
|
190
|
+
'logo': 'https://github.com/user-attachments/assets/bfffb73d-29bd-465d-b75b-98e210491769',
|
|
191
|
+
'api': {
|
|
192
|
+
'public': 'https://api.bydfi.com/api',
|
|
193
|
+
'private': 'https://api.bydfi.com/api',
|
|
194
|
+
},
|
|
195
|
+
'www': 'https://bydfi.com/',
|
|
196
|
+
'doc': 'https://developers.bydfi.com/en/',
|
|
197
|
+
'referral': 'https://partner.bydfi.com/j/DilWutCI',
|
|
198
|
+
},
|
|
199
|
+
'fees': {},
|
|
200
|
+
'api': {
|
|
201
|
+
'public': {
|
|
202
|
+
'get': {
|
|
203
|
+
'v1/public/api_limits': 1,
|
|
204
|
+
'v1/swap/market/exchange_info': 1,
|
|
205
|
+
'v1/swap/market/depth': 1,
|
|
206
|
+
'v1/swap/market/trades': 1,
|
|
207
|
+
'v1/swap/market/klines': 1,
|
|
208
|
+
'v1/swap/market/ticker/24hr': 1,
|
|
209
|
+
'v1/swap/market/ticker/price': 1,
|
|
210
|
+
'v1/swap/market/mark_price': 1,
|
|
211
|
+
'v1/swap/market/funding_rate': 1,
|
|
212
|
+
'v1/swap/market/funding_rate_history': 1,
|
|
213
|
+
'v1/swap/market/risk_limit': 1, // https://developers.bydfi.com/en/swap/market#risk-limit
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
'private': {
|
|
217
|
+
'get': {
|
|
218
|
+
'v1/account/assets': 1,
|
|
219
|
+
'v1/account/transfer_records': 1,
|
|
220
|
+
'v1/spot/deposit_records': 1,
|
|
221
|
+
'v1/spot/withdraw_records': 1,
|
|
222
|
+
'v1/swap/trade/open_order': 1,
|
|
223
|
+
'v1/swap/trade/plan_order': 1,
|
|
224
|
+
'v1/swap/trade/leverage': 1,
|
|
225
|
+
'v1/swap/trade/history_order': 1,
|
|
226
|
+
'v1/swap/trade/history_trade': 1,
|
|
227
|
+
'v1/swap/trade/position_history': 1,
|
|
228
|
+
'v1/swap/trade/positions': 1,
|
|
229
|
+
'v1/swap/account/balance': 1,
|
|
230
|
+
'v1/swap/user_data/assets_margin': 1,
|
|
231
|
+
'v1/swap/user_data/position_side/dual': 1,
|
|
232
|
+
'v1/agent/teams': 1,
|
|
233
|
+
'v1/agent/agent_links': 1,
|
|
234
|
+
'v1/agent/regular_overview': 1,
|
|
235
|
+
'v1/agent/agent_sub_overview': 1,
|
|
236
|
+
'v1/agent/partener_user_deposit': 1,
|
|
237
|
+
'v1/agent/partener_users_data': 1,
|
|
238
|
+
'v1/agent/affiliate_uids': 1,
|
|
239
|
+
'v1/agent/affiliate_commission': 1,
|
|
240
|
+
'v1/agent/internal_withdrawal_status': 1, // https://developers.bydfi.com/en/agent/#get-internal-withdrawal-status
|
|
241
|
+
},
|
|
242
|
+
'post': {
|
|
243
|
+
'v1/account/transfer': 1,
|
|
244
|
+
'v1/swap/trade/place_order': 1,
|
|
245
|
+
'v1/swap/trade/batch_place_order': 1,
|
|
246
|
+
'v1/swap/trade/edit_order': 1,
|
|
247
|
+
'v1/swap/trade/batch_edit_order': 1,
|
|
248
|
+
'v1/swap/trade/cancel_all_order': 1,
|
|
249
|
+
'v1/swap/trade/leverage': 1,
|
|
250
|
+
'v1/swap/trade/batch_leverage_margin': 1,
|
|
251
|
+
'v1/swap/user_data/margin_type': 1,
|
|
252
|
+
'v1/swap/user_data/position_side/dual': 1,
|
|
253
|
+
'v1/agent/internal_withdrawal': 1, // https://developers.bydfi.com/en/agent/#internal-withdrawal
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
'features': {
|
|
258
|
+
'spot': undefined,
|
|
259
|
+
'swap': {
|
|
260
|
+
'linear': {
|
|
261
|
+
'sandbox': false,
|
|
262
|
+
'createOrder': {
|
|
263
|
+
'marginMode': false,
|
|
264
|
+
'triggerPrice': false,
|
|
265
|
+
'triggerPriceType': {
|
|
266
|
+
'mark': true,
|
|
267
|
+
'last': true,
|
|
268
|
+
'index': false,
|
|
269
|
+
},
|
|
270
|
+
'stopLossPrice': true,
|
|
271
|
+
'takeProfitPrice': true,
|
|
272
|
+
'attachedStopLossTakeProfit': undefined,
|
|
273
|
+
'timeInForce': {
|
|
274
|
+
'IOC': true,
|
|
275
|
+
'FOK': true,
|
|
276
|
+
'PO': true,
|
|
277
|
+
'GTD': false,
|
|
278
|
+
},
|
|
279
|
+
'hedged': true,
|
|
280
|
+
'selfTradePrevention': false,
|
|
281
|
+
'trailing': true,
|
|
282
|
+
'iceberg': false,
|
|
283
|
+
'leverage': false,
|
|
284
|
+
'marketBuyRequiresPrice': false,
|
|
285
|
+
'marketBuyByCost': false,
|
|
286
|
+
},
|
|
287
|
+
'createOrders': {
|
|
288
|
+
'max': 5,
|
|
289
|
+
},
|
|
290
|
+
'fetchMyTrades': {
|
|
291
|
+
'marginMode': false,
|
|
292
|
+
'daysBack': 182,
|
|
293
|
+
'limit': 500,
|
|
294
|
+
'untilDays': 7,
|
|
295
|
+
'symbolRequired': false,
|
|
296
|
+
},
|
|
297
|
+
'fetchOrder': undefined,
|
|
298
|
+
'fetchOpenOrder': {
|
|
299
|
+
'marginMode': false,
|
|
300
|
+
'trigger': true,
|
|
301
|
+
'trailing': false,
|
|
302
|
+
'symbolRequired': true,
|
|
303
|
+
},
|
|
304
|
+
'fetchOpenOrders': {
|
|
305
|
+
'marginMode': false,
|
|
306
|
+
'limit': 500,
|
|
307
|
+
'trigger': true,
|
|
308
|
+
'trailing': false,
|
|
309
|
+
'symbolRequired': true,
|
|
310
|
+
},
|
|
311
|
+
'fetchOrders': undefined,
|
|
312
|
+
'fetchCanceledAndClosedOrders': {
|
|
313
|
+
'marginMode': false,
|
|
314
|
+
'limit': 500,
|
|
315
|
+
'daysBack': 182,
|
|
316
|
+
'untilDays': 7,
|
|
317
|
+
'trigger': false,
|
|
318
|
+
'trailing': false,
|
|
319
|
+
'symbolRequired': false,
|
|
320
|
+
},
|
|
321
|
+
'fetchClosedOrders': undefined,
|
|
322
|
+
'fetchOHLCV': {
|
|
323
|
+
'limit': 500,
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
'inverse': undefined,
|
|
327
|
+
},
|
|
328
|
+
'future': {
|
|
329
|
+
'linear': undefined,
|
|
330
|
+
'inverse': undefined,
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
'timeframes': {
|
|
334
|
+
'1m': '1m',
|
|
335
|
+
'3m': '3m',
|
|
336
|
+
'5m': '5m',
|
|
337
|
+
'15m': '15m',
|
|
338
|
+
'30m': '30m',
|
|
339
|
+
'1h': '1h',
|
|
340
|
+
'2h': '2h',
|
|
341
|
+
'4h': '4h',
|
|
342
|
+
'6h': '6h',
|
|
343
|
+
'12h': '12h',
|
|
344
|
+
'1d': '1d',
|
|
345
|
+
},
|
|
346
|
+
'precisionMode': TICK_SIZE,
|
|
347
|
+
'exceptions': {
|
|
348
|
+
'exact': {
|
|
349
|
+
'101001': AuthenticationError,
|
|
350
|
+
'101103': AuthenticationError,
|
|
351
|
+
'102001': BadRequest,
|
|
352
|
+
'102002': PermissionDenied,
|
|
353
|
+
'401': AuthenticationError,
|
|
354
|
+
'500': ExchangeError,
|
|
355
|
+
'501': ExchangeError,
|
|
356
|
+
'506': ExchangeError,
|
|
357
|
+
'510': RateLimitExceeded,
|
|
358
|
+
'511': AuthenticationError,
|
|
359
|
+
'513': BadRequest,
|
|
360
|
+
'514': BadRequest,
|
|
361
|
+
'600': BadRequest,
|
|
362
|
+
'Position does not exist': BadRequest,
|
|
363
|
+
'Requires transaction permissions': PermissionDenied,
|
|
364
|
+
'Service error': ExchangeError,
|
|
365
|
+
'transfer failed': InsufficientFunds, // {"code":500,"message":"transfer failed","success":false}
|
|
366
|
+
},
|
|
367
|
+
'broad': {
|
|
368
|
+
'is missing': ArgumentsRequired, // {"code":600,"message":"The parameter 'startTime' is missing"}
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
'commonCurrencies': {},
|
|
372
|
+
'options': {
|
|
373
|
+
'networks': {
|
|
374
|
+
'ERC20': 'ETH', // todo add more networks
|
|
375
|
+
},
|
|
376
|
+
'timeInForce': {
|
|
377
|
+
'GTC': 'GTC',
|
|
378
|
+
'FOK': 'FOK',
|
|
379
|
+
'IOC': 'IOC',
|
|
380
|
+
'PO': 'POST_ONLY', // Post Only
|
|
381
|
+
},
|
|
382
|
+
'accountsByType': {
|
|
383
|
+
'spot': 'SPOT',
|
|
384
|
+
'swap': 'SWAP',
|
|
385
|
+
'funding': 'FUND',
|
|
386
|
+
},
|
|
387
|
+
'accountsById': {
|
|
388
|
+
'SPOT': 'spot',
|
|
389
|
+
'SWAP': 'swap',
|
|
390
|
+
'FUND': 'funding',
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* @method
|
|
397
|
+
* @name bydfi#fetchMarkets
|
|
398
|
+
* @description retrieves data on all markets for bydfi
|
|
399
|
+
* @see https://developers.bydfi.com/en/swap/market#fetching-trading-rules-and-pairs
|
|
400
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
401
|
+
* @returns {object[]} an array of objects representing market data
|
|
402
|
+
*/
|
|
403
|
+
async fetchMarkets(params = {}) {
|
|
404
|
+
const response = await this.publicGetV1SwapMarketExchangeInfo(params);
|
|
405
|
+
//
|
|
406
|
+
// {
|
|
407
|
+
// "code": "200",
|
|
408
|
+
// "message": "success",
|
|
409
|
+
// "data": [
|
|
410
|
+
// {
|
|
411
|
+
// "symbol": "CLANKER-USDT",
|
|
412
|
+
// "baseAsset": "CLANKER",
|
|
413
|
+
// "marginAsset": "USDT",
|
|
414
|
+
// "quoteAsset": "USDT",
|
|
415
|
+
// "contractFactor": "0.01",
|
|
416
|
+
// "limitMaxQty": "50000",
|
|
417
|
+
// "limitMinQty": "1",
|
|
418
|
+
// "marketMaxQty": "10000",
|
|
419
|
+
// "marketMinQty": "1",
|
|
420
|
+
// "pricePrecision": "8",
|
|
421
|
+
// "basePrecision": "8",
|
|
422
|
+
// "feeRateTaker": "0.0006",
|
|
423
|
+
// "feeRateMaker": "0.0002",
|
|
424
|
+
// "liqFeeRate": "0.0006",
|
|
425
|
+
// "openBuyLimitRateMax": "0.05",
|
|
426
|
+
// "openSellLimitRateMax": "100",
|
|
427
|
+
// "openBuyLimitRateMin": "0.98",
|
|
428
|
+
// "openSellLimitRateMin": "0.05",
|
|
429
|
+
// "priceOrderPrecision": "2",
|
|
430
|
+
// "baseShowPrecision": "2",
|
|
431
|
+
// "maxLeverageLevel": "20",
|
|
432
|
+
// "volumePrecision": "2",
|
|
433
|
+
// "maxLimitOrderNum": "200",
|
|
434
|
+
// "maxPlanOrderNum": "10",
|
|
435
|
+
// "reverse": false,
|
|
436
|
+
// "onboardTime": "1763373600000",
|
|
437
|
+
// "status": "NORMAL"
|
|
438
|
+
// },
|
|
439
|
+
// ...
|
|
440
|
+
// ],
|
|
441
|
+
// "success": true
|
|
442
|
+
// }
|
|
443
|
+
const data = this.safeList(response, 'data', []);
|
|
444
|
+
return this.parseMarkets(data);
|
|
445
|
+
}
|
|
446
|
+
parseMarket(market) {
|
|
447
|
+
//
|
|
448
|
+
// {
|
|
449
|
+
// "symbol": "CLANKER-USDT",
|
|
450
|
+
// "baseAsset": "CLANKER",
|
|
451
|
+
// "marginAsset": "USDT",
|
|
452
|
+
// "quoteAsset": "USDT",
|
|
453
|
+
// "contractFactor": "0.01",
|
|
454
|
+
// "limitMaxQty": "50000",
|
|
455
|
+
// "limitMinQty": "1",
|
|
456
|
+
// "marketMaxQty": "10000",
|
|
457
|
+
// "marketMinQty": "1",
|
|
458
|
+
// "pricePrecision": "8",
|
|
459
|
+
// "basePrecision": "8",
|
|
460
|
+
// "feeRateTaker": "0.0006",
|
|
461
|
+
// "feeRateMaker": "0.0002",
|
|
462
|
+
// "liqFeeRate": "0.0006",
|
|
463
|
+
// "openBuyLimitRateMax": "0.05",
|
|
464
|
+
// "openSellLimitRateMax": "100",
|
|
465
|
+
// "openBuyLimitRateMin": "0.98",
|
|
466
|
+
// "openSellLimitRateMin": "0.05",
|
|
467
|
+
// "priceOrderPrecision": "2",
|
|
468
|
+
// "baseShowPrecision": "2",
|
|
469
|
+
// "maxLeverageLevel": "20",
|
|
470
|
+
// "volumePrecision": "2",
|
|
471
|
+
// "maxLimitOrderNum": "200",
|
|
472
|
+
// "maxPlanOrderNum": "10",
|
|
473
|
+
// "reverse": false,
|
|
474
|
+
// "onboardTime": "1763373600000",
|
|
475
|
+
// "status": "NORMAL"
|
|
476
|
+
// }
|
|
477
|
+
//
|
|
478
|
+
const id = this.safeString(market, 'symbol');
|
|
479
|
+
const baseId = this.safeString(market, 'baseAsset');
|
|
480
|
+
const quoteId = this.safeString(market, 'quoteAsset');
|
|
481
|
+
const settleId = this.safeString(market, 'marginAsset');
|
|
482
|
+
const base = this.safeCurrencyCode(baseId);
|
|
483
|
+
const quote = this.safeCurrencyCode(quoteId);
|
|
484
|
+
const settle = this.safeCurrencyCode(settleId);
|
|
485
|
+
const symbol = base + '/' + quote + ':' + settle;
|
|
486
|
+
const inverse = this.safeBool(market, 'reverse');
|
|
487
|
+
const limitMaxQty = this.safeString(market, 'limitMaxQty');
|
|
488
|
+
const marketMaxQty = this.safeString(market, 'marketMaxQty');
|
|
489
|
+
const maxAmountString = Precise.stringMax(limitMaxQty, marketMaxQty);
|
|
490
|
+
const marketMinQty = this.safeString(market, 'marketMinQty');
|
|
491
|
+
const limitMinQty = this.safeString(market, 'limitMinQty');
|
|
492
|
+
const minAmountString = Precise.stringMin(marketMinQty, limitMinQty);
|
|
493
|
+
const contractSize = this.safeString(market, 'contractFactor');
|
|
494
|
+
const pricePrecision = this.parsePrecision(this.safeString(market, 'priceOrderPrecision'));
|
|
495
|
+
const rawAmountPrecision = this.parsePrecision(this.safeString(market, 'volumePrecision'));
|
|
496
|
+
const amountPrecision = Precise.stringDiv(rawAmountPrecision, contractSize);
|
|
497
|
+
const basePrecision = this.parsePrecision(this.safeString(market, 'basePrecision'));
|
|
498
|
+
const taker = this.safeNumber(market, 'feeRateTaker');
|
|
499
|
+
const maker = this.safeNumber(market, 'feeRateMaker');
|
|
500
|
+
const maxLeverage = this.safeNumber(market, 'maxLeverageLevel');
|
|
501
|
+
const status = this.safeString(market, 'status');
|
|
502
|
+
return this.safeMarketStructure({
|
|
503
|
+
'id': id,
|
|
504
|
+
'symbol': symbol,
|
|
505
|
+
'base': base,
|
|
506
|
+
'quote': quote,
|
|
507
|
+
'settle': settle,
|
|
508
|
+
'baseId': baseId,
|
|
509
|
+
'quoteId': quoteId,
|
|
510
|
+
'settleId': settleId,
|
|
511
|
+
'type': 'swap',
|
|
512
|
+
'spot': false,
|
|
513
|
+
'margin': undefined,
|
|
514
|
+
'swap': true,
|
|
515
|
+
'future': false,
|
|
516
|
+
'option': false,
|
|
517
|
+
'active': status === 'NORMAL',
|
|
518
|
+
'contract': true,
|
|
519
|
+
'linear': !inverse,
|
|
520
|
+
'inverse': inverse,
|
|
521
|
+
'taker': taker,
|
|
522
|
+
'maker': maker,
|
|
523
|
+
'contractSize': this.parseNumber(contractSize),
|
|
524
|
+
'expiry': undefined,
|
|
525
|
+
'expiryDatetime': undefined,
|
|
526
|
+
'strike': undefined,
|
|
527
|
+
'optionType': undefined,
|
|
528
|
+
'precision': {
|
|
529
|
+
'amount': this.parseNumber(amountPrecision),
|
|
530
|
+
'price': this.parseNumber(pricePrecision),
|
|
531
|
+
'base': this.parseNumber(basePrecision),
|
|
532
|
+
},
|
|
533
|
+
'limits': {
|
|
534
|
+
'leverage': {
|
|
535
|
+
'min': undefined,
|
|
536
|
+
'max': maxLeverage,
|
|
537
|
+
},
|
|
538
|
+
'amount': {
|
|
539
|
+
'min': this.parseNumber(minAmountString),
|
|
540
|
+
'max': this.parseNumber(maxAmountString),
|
|
541
|
+
},
|
|
542
|
+
'price': {
|
|
543
|
+
'min': undefined,
|
|
544
|
+
'max': undefined,
|
|
545
|
+
},
|
|
546
|
+
'cost': {
|
|
547
|
+
'min': undefined,
|
|
548
|
+
'max': undefined,
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
'created': this.parse8601(this.safeString(market, 'createdAt')),
|
|
552
|
+
'info': market,
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* @method
|
|
557
|
+
* @name bydfi#fetchOrderBook
|
|
558
|
+
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
559
|
+
* @see https://developers.bydfi.com/en/swap/market#depth-information
|
|
560
|
+
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
561
|
+
* @param {int} [limit] the maximum amount of order book entries to return, could be 5, 10, 20, 50, 100, 500 or 1000 (default 500)
|
|
562
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
563
|
+
* @param {string} [params.loc] crypto location, default: us
|
|
564
|
+
* @returns {object} A dictionary of [order book structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure} indexed by market symbols
|
|
565
|
+
*/
|
|
566
|
+
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
567
|
+
await this.loadMarkets();
|
|
568
|
+
const market = this.market(symbol);
|
|
569
|
+
const request = {
|
|
570
|
+
'symbol': market['id'],
|
|
571
|
+
};
|
|
572
|
+
if (limit !== undefined) {
|
|
573
|
+
request['limit'] = this.getClosestLimit(limit);
|
|
574
|
+
}
|
|
575
|
+
const response = await this.publicGetV1SwapMarketDepth(this.extend(request, params));
|
|
576
|
+
//
|
|
577
|
+
// {
|
|
578
|
+
// "code": 200,
|
|
579
|
+
// "message": "success",
|
|
580
|
+
// "data": {
|
|
581
|
+
// "lastUpdateId": "221780076",
|
|
582
|
+
// "symbol": "ETH-USDT",
|
|
583
|
+
// "asks": [
|
|
584
|
+
// {
|
|
585
|
+
// "price": "2958.21",
|
|
586
|
+
// "amount": "39478"
|
|
587
|
+
// },
|
|
588
|
+
// ...
|
|
589
|
+
// ],
|
|
590
|
+
// "bids": [
|
|
591
|
+
// {
|
|
592
|
+
// "price": "2958.19",
|
|
593
|
+
// "amount": "174498"
|
|
594
|
+
// },
|
|
595
|
+
// ...
|
|
596
|
+
// ],
|
|
597
|
+
// "e": "221780076"
|
|
598
|
+
// },
|
|
599
|
+
// "success": true
|
|
600
|
+
// }
|
|
601
|
+
//
|
|
602
|
+
const data = this.safeDict(response, 'data', {});
|
|
603
|
+
const timestamp = this.milliseconds();
|
|
604
|
+
const orderBook = this.parseOrderBook(data, market['symbol'], timestamp, 'bids', 'asks', 'price', 'amount');
|
|
605
|
+
orderBook['nonce'] = this.safeInteger(data, 'lastUpdateId');
|
|
606
|
+
return orderBook;
|
|
607
|
+
}
|
|
608
|
+
getClosestLimit(limit) {
|
|
609
|
+
const limits = [5, 10, 20, 50, 100, 500, 1000];
|
|
610
|
+
let result = 1000;
|
|
611
|
+
for (let i = 0; i < limits.length; i++) {
|
|
612
|
+
if (limit <= limits[i]) {
|
|
613
|
+
result = limits[i];
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return result;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* @method
|
|
621
|
+
* @name bydfi#fetchTrades
|
|
622
|
+
* @description get the list of most recent trades for a particular symbol
|
|
623
|
+
* @see https://developers.bydfi.com/en/swap/market#recent-trades
|
|
624
|
+
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
625
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
626
|
+
* @param {int} [limit] the maximum amount of trades to fetch (default 500, max 1000)
|
|
627
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
628
|
+
* @param {int} [params.fromId] retrieve from which trade ID to start. Default to retrieve the most recent trade records
|
|
629
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
|
|
630
|
+
*/
|
|
631
|
+
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
632
|
+
await this.loadMarkets();
|
|
633
|
+
const market = this.market(symbol);
|
|
634
|
+
const request = {
|
|
635
|
+
'symbol': market['id'],
|
|
636
|
+
};
|
|
637
|
+
if (limit !== undefined) {
|
|
638
|
+
request['limit'] = limit;
|
|
639
|
+
}
|
|
640
|
+
const response = await this.publicGetV1SwapMarketTrades(this.extend(request, params));
|
|
641
|
+
//
|
|
642
|
+
// {
|
|
643
|
+
// "code": 200,
|
|
644
|
+
// "message": "success",
|
|
645
|
+
// "data": [
|
|
646
|
+
// {
|
|
647
|
+
// "id": "7407825178362667008",
|
|
648
|
+
// "symbol": "ETH-USDT",
|
|
649
|
+
// "price": "2970.49",
|
|
650
|
+
// "quantity": "63",
|
|
651
|
+
// "side": "SELL",
|
|
652
|
+
// "time": 1766163153218
|
|
653
|
+
// }
|
|
654
|
+
// ],
|
|
655
|
+
// "success": true
|
|
656
|
+
// }
|
|
657
|
+
//
|
|
658
|
+
const data = this.safeList(response, 'data', []);
|
|
659
|
+
return this.parseTrades(data, market, since, limit);
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* @method
|
|
663
|
+
* @name bydfi#fetchMyTrades
|
|
664
|
+
* @description fetch all trades made by the user
|
|
665
|
+
* @see https://developers.bydfi.com/en/swap/trade#historical-trades-query
|
|
666
|
+
* @param {string} symbol unified market symbol
|
|
667
|
+
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
668
|
+
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
669
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
670
|
+
* @param {int} [params.until] the latest time in ms to fetch trades for
|
|
671
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
672
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet
|
|
673
|
+
* @param {string} [params.orderType] order type ('LIMIT', 'MARKET', 'LIQ', 'LIMIT_CLOSE', 'MARKET_CLOSE', 'STOP', 'TAKE_PROFIT', 'STOP_MARKET', 'TAKE_PROFIT_MARKET' or 'TRAILING_STOP_MARKET')
|
|
674
|
+
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure}
|
|
675
|
+
*/
|
|
676
|
+
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
677
|
+
await this.loadMarkets();
|
|
678
|
+
const paginate = this.safeBool(params, 'paginate', false);
|
|
679
|
+
if (paginate) {
|
|
680
|
+
const maxLimit = 500;
|
|
681
|
+
params = this.omit(params, 'paginate');
|
|
682
|
+
params = this.extend(params, { 'paginationDirection': 'backward' });
|
|
683
|
+
const paginatedResponse = await this.fetchPaginatedCallDynamic('fetchMyTrades', symbol, since, limit, params, maxLimit, true);
|
|
684
|
+
return this.sortBy(paginatedResponse, 'timestamp');
|
|
685
|
+
}
|
|
686
|
+
let contractType = 'FUTURE';
|
|
687
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'contractType', contractType);
|
|
688
|
+
const request = {
|
|
689
|
+
'contractType': contractType,
|
|
690
|
+
};
|
|
691
|
+
let market = undefined;
|
|
692
|
+
if (symbol !== undefined) {
|
|
693
|
+
market = this.market(symbol);
|
|
694
|
+
request['symbol'] = market['id'];
|
|
695
|
+
}
|
|
696
|
+
params = this.handleSinceAndUntil('fetchMyTrades', since, params);
|
|
697
|
+
if (limit !== undefined) {
|
|
698
|
+
request['limit'] = limit;
|
|
699
|
+
}
|
|
700
|
+
const response = await this.privateGetV1SwapTradeHistoryTrade(this.extend(request, params));
|
|
701
|
+
//
|
|
702
|
+
// {
|
|
703
|
+
// "code": 200,
|
|
704
|
+
// "message": "success",
|
|
705
|
+
// "data": [
|
|
706
|
+
// {
|
|
707
|
+
// "orderId": "7408919189505597440",
|
|
708
|
+
// "wallet": "W001",
|
|
709
|
+
// "symbol": "ETH-USDC",
|
|
710
|
+
// "time": "1766423985842",
|
|
711
|
+
// "dealPrice": "3032.45",
|
|
712
|
+
// "dealVolume": "1",
|
|
713
|
+
// "fee": "0",
|
|
714
|
+
// "side": "BUY",
|
|
715
|
+
// "type": "2",
|
|
716
|
+
// "liqPrice": null,
|
|
717
|
+
// "basePrecision": "8",
|
|
718
|
+
// "baseShowPrecision": "2",
|
|
719
|
+
// "tradePnl": "0",
|
|
720
|
+
// "marginType": "CROSS",
|
|
721
|
+
// "leverageLevel": 1
|
|
722
|
+
// }
|
|
723
|
+
// ],
|
|
724
|
+
// "success": true
|
|
725
|
+
// }
|
|
726
|
+
//
|
|
727
|
+
const data = this.safeList(response, 'data', []);
|
|
728
|
+
return this.parseTrades(data, market, since, limit);
|
|
729
|
+
}
|
|
730
|
+
parseTrade(trade, market = undefined) {
|
|
731
|
+
//
|
|
732
|
+
// fetchTrades
|
|
733
|
+
// {
|
|
734
|
+
// "id": "7407825178362667008",
|
|
735
|
+
// "symbol": "ETH-USDT",
|
|
736
|
+
// "price": "2970.49",
|
|
737
|
+
// "quantity": "63",
|
|
738
|
+
// "side": "SELL",
|
|
739
|
+
// "time": 1766163153218
|
|
740
|
+
// }
|
|
741
|
+
//
|
|
742
|
+
// fetchMyTrades
|
|
743
|
+
// {
|
|
744
|
+
// "orderId": "7408919189505597440",
|
|
745
|
+
// "wallet": "W001",
|
|
746
|
+
// "symbol": "ETH-USDC",
|
|
747
|
+
// "time": "1766423985842",
|
|
748
|
+
// "dealPrice": "3032.45",
|
|
749
|
+
// "dealVolume": "1",
|
|
750
|
+
// "fee": "0",
|
|
751
|
+
// "side": "BUY",
|
|
752
|
+
// "type": "2",
|
|
753
|
+
// "liqPrice": null,
|
|
754
|
+
// "basePrecision": "8",
|
|
755
|
+
// "baseShowPrecision": "2",
|
|
756
|
+
// "tradePnl": "0",
|
|
757
|
+
// "marginType": "CROSS",
|
|
758
|
+
// "leverageLevel": 1
|
|
759
|
+
// }
|
|
760
|
+
//
|
|
761
|
+
const marketId = this.safeString(trade, 'symbol');
|
|
762
|
+
market = this.safeMarket(marketId, market);
|
|
763
|
+
const timestamp = this.safeInteger(trade, 'time');
|
|
764
|
+
let fee = undefined;
|
|
765
|
+
const rawType = this.safeString(trade, 'type');
|
|
766
|
+
const feeCost = this.safeString(trade, 'fee');
|
|
767
|
+
if (feeCost !== undefined) {
|
|
768
|
+
fee = {
|
|
769
|
+
'cost': feeCost,
|
|
770
|
+
'currency': market['settle'],
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
const orderId = this.safeString(trade, 'orderId');
|
|
774
|
+
let side = undefined; // fetchMyTrades always returns side BUY
|
|
775
|
+
if (orderId === undefined) {
|
|
776
|
+
// from fetchTrades
|
|
777
|
+
side = this.safeStringLower(trade, 'side');
|
|
778
|
+
}
|
|
779
|
+
return this.safeTrade({
|
|
780
|
+
'info': trade,
|
|
781
|
+
'timestamp': timestamp,
|
|
782
|
+
'datetime': this.iso8601(timestamp),
|
|
783
|
+
'symbol': market['symbol'],
|
|
784
|
+
'id': this.safeString(trade, 'id'),
|
|
785
|
+
'order': orderId,
|
|
786
|
+
'type': this.parseTradeType(rawType),
|
|
787
|
+
'side': side,
|
|
788
|
+
'takerOrMaker': undefined,
|
|
789
|
+
'price': this.safeString2(trade, 'price', 'dealPrice'),
|
|
790
|
+
'amount': this.safeString2(trade, 'quantity', 'dealVolume'),
|
|
791
|
+
'cost': undefined,
|
|
792
|
+
'fee': fee,
|
|
793
|
+
}, market);
|
|
794
|
+
}
|
|
795
|
+
parseTradeType(type) {
|
|
796
|
+
const types = {
|
|
797
|
+
'1': 'limit',
|
|
798
|
+
'2': 'market',
|
|
799
|
+
'3': 'liquidation',
|
|
800
|
+
};
|
|
801
|
+
return this.safeString(types, type, type);
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* @method
|
|
805
|
+
* @name bydfi#fetchOHLCV
|
|
806
|
+
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
807
|
+
* @see https://developers.bydfi.com/en/swap/market#candlestick-data
|
|
808
|
+
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
809
|
+
* @param {string} timeframe the length of time each candle represents
|
|
810
|
+
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
811
|
+
* @param {int} [limit] the maximum amount of candles to fetch (max 500)
|
|
812
|
+
* @param {object} [params] extra parameters specific to the bitteam api endpoint
|
|
813
|
+
* @param {int} [params.until] timestamp in ms of the latest candle to fetch
|
|
814
|
+
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
815
|
+
*/
|
|
816
|
+
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
817
|
+
await this.loadMarkets();
|
|
818
|
+
const maxLimit = 500; // docs says max 1500, but in practice only 500 works
|
|
819
|
+
let paginate = false;
|
|
820
|
+
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
|
|
821
|
+
if (paginate) {
|
|
822
|
+
return this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit);
|
|
823
|
+
}
|
|
824
|
+
const market = this.market(symbol);
|
|
825
|
+
const interval = this.safeString(this.timeframes, timeframe, timeframe);
|
|
826
|
+
const request = {
|
|
827
|
+
'symbol': market['id'],
|
|
828
|
+
'interval': interval,
|
|
829
|
+
};
|
|
830
|
+
let startTime = since;
|
|
831
|
+
const numberOfCandles = limit ? limit : maxLimit;
|
|
832
|
+
let until = undefined;
|
|
833
|
+
[until, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'until');
|
|
834
|
+
const now = this.milliseconds();
|
|
835
|
+
const duration = this.parseTimeframe(timeframe) * 1000;
|
|
836
|
+
const timeDelta = duration * numberOfCandles;
|
|
837
|
+
if (startTime === undefined && until === undefined) {
|
|
838
|
+
startTime = now - timeDelta;
|
|
839
|
+
until = now;
|
|
840
|
+
}
|
|
841
|
+
else if (until === undefined) {
|
|
842
|
+
until = startTime + timeDelta;
|
|
843
|
+
if (until > now) {
|
|
844
|
+
until = now;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
else if (startTime === undefined) {
|
|
848
|
+
startTime = until - timeDelta;
|
|
849
|
+
}
|
|
850
|
+
request['startTime'] = startTime;
|
|
851
|
+
request['endTime'] = until;
|
|
852
|
+
if (limit !== undefined) {
|
|
853
|
+
request['limit'] = limit;
|
|
854
|
+
}
|
|
855
|
+
const response = await this.publicGetV1SwapMarketKlines(this.extend(request, params));
|
|
856
|
+
//
|
|
857
|
+
// {
|
|
858
|
+
// "code": 200,
|
|
859
|
+
// "message": "success",
|
|
860
|
+
// "data": [
|
|
861
|
+
// {
|
|
862
|
+
// "s": "ETH-USDT",
|
|
863
|
+
// "t": "1766166000000",
|
|
864
|
+
// "c": "2964.990000000000000000",
|
|
865
|
+
// "o": "2967.830000000000000000",
|
|
866
|
+
// "h": "2967.830000000000000000",
|
|
867
|
+
// "l": "2964.130000000000000000",
|
|
868
|
+
// "v": "20358.000000000000000000"
|
|
869
|
+
// }
|
|
870
|
+
// ],
|
|
871
|
+
// "success": true
|
|
872
|
+
// }
|
|
873
|
+
//
|
|
874
|
+
const data = this.safeList(response, 'data', []);
|
|
875
|
+
const result = this.parseOHLCVs(data, market, timeframe, since, limit);
|
|
876
|
+
return result;
|
|
877
|
+
}
|
|
878
|
+
parseOHLCV(ohlcv, market = undefined) {
|
|
879
|
+
//
|
|
880
|
+
// {
|
|
881
|
+
// "s": "ETH-USDT",
|
|
882
|
+
// "t": "1766166000000",
|
|
883
|
+
// "c": "2964.990000000000000000",
|
|
884
|
+
// "o": "2967.830000000000000000",
|
|
885
|
+
// "h": "2967.830000000000000000",
|
|
886
|
+
// "l": "2964.130000000000000000",
|
|
887
|
+
// "v": "20358.000000000000000000"
|
|
888
|
+
// }
|
|
889
|
+
//
|
|
890
|
+
return [
|
|
891
|
+
this.safeInteger(ohlcv, 't'),
|
|
892
|
+
this.safeNumber(ohlcv, 'o'),
|
|
893
|
+
this.safeNumber(ohlcv, 'h'),
|
|
894
|
+
this.safeNumber(ohlcv, 'l'),
|
|
895
|
+
this.safeNumber(ohlcv, 'c'),
|
|
896
|
+
this.safeNumber(ohlcv, 'v'),
|
|
897
|
+
];
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* @method
|
|
901
|
+
* @name bydfi#fetchTickers
|
|
902
|
+
* @see https://developers.bydfi.com/en/swap/market#24hr-price-change-statistics
|
|
903
|
+
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
904
|
+
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
905
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
906
|
+
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
907
|
+
*/
|
|
908
|
+
async fetchTickers(symbols = undefined, params = {}) {
|
|
909
|
+
await this.loadMarkets();
|
|
910
|
+
const response = await this.publicGetV1SwapMarketTicker24hr(params);
|
|
911
|
+
//
|
|
912
|
+
// {
|
|
913
|
+
// "code": 200,
|
|
914
|
+
// "message": "success",
|
|
915
|
+
// "data": [
|
|
916
|
+
// {
|
|
917
|
+
// "symbol": "BTC-USDT",
|
|
918
|
+
// "open": "86452.9",
|
|
919
|
+
// "high": "89371.2",
|
|
920
|
+
// "low": "84418.5",
|
|
921
|
+
// "last": "87050.3",
|
|
922
|
+
// "vol": "12938783",
|
|
923
|
+
// "time": 1766169423872
|
|
924
|
+
// }
|
|
925
|
+
// ],
|
|
926
|
+
// "success": true
|
|
927
|
+
// }
|
|
928
|
+
//
|
|
929
|
+
const data = this.safeList(response, 'data', []);
|
|
930
|
+
return this.parseTickers(data, symbols);
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* @method
|
|
934
|
+
* @name bydfi#fetchTicker
|
|
935
|
+
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
936
|
+
* @see https://developers.bydfi.com/en/swap/market#24hr-price-change-statistics
|
|
937
|
+
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
938
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
939
|
+
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
|
|
940
|
+
*/
|
|
941
|
+
async fetchTicker(symbol, params = {}) {
|
|
942
|
+
await this.loadMarkets();
|
|
943
|
+
const market = this.market(symbol);
|
|
944
|
+
const request = {
|
|
945
|
+
'symbol': market['id'],
|
|
946
|
+
};
|
|
947
|
+
const response = await this.publicGetV1SwapMarketTicker24hr(this.extend(request, params));
|
|
948
|
+
const data = this.safeList(response, 'data', []);
|
|
949
|
+
const ticker = this.safeDict(data, 0, {});
|
|
950
|
+
return this.parseTicker(ticker, market);
|
|
951
|
+
}
|
|
952
|
+
parseTicker(ticker, market = undefined) {
|
|
953
|
+
//
|
|
954
|
+
// fetchTicker/fetchTickers
|
|
955
|
+
// {
|
|
956
|
+
// "symbol": "BTC-USDT",
|
|
957
|
+
// "open": "86452.9",
|
|
958
|
+
// "high": "89371.2",
|
|
959
|
+
// "low": "84418.5",
|
|
960
|
+
// "last": "87050.3",
|
|
961
|
+
// "vol": "12938783",
|
|
962
|
+
// "time": 1766169423872
|
|
963
|
+
// }
|
|
964
|
+
//
|
|
965
|
+
const marketId = this.safeString2(ticker, 'symbol', 's');
|
|
966
|
+
market = this.safeMarket(marketId, market);
|
|
967
|
+
const timestamp = this.safeInteger2(ticker, 'time', 'E');
|
|
968
|
+
const last = this.safeString2(ticker, 'last', 'c');
|
|
969
|
+
return this.safeTicker({
|
|
970
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
971
|
+
'timestamp': timestamp,
|
|
972
|
+
'datetime': this.iso8601(timestamp),
|
|
973
|
+
'high': this.safeString2(ticker, 'high', 'h'),
|
|
974
|
+
'low': this.safeString2(ticker, 'low', 'l'),
|
|
975
|
+
'bid': undefined,
|
|
976
|
+
'bidVolume': undefined,
|
|
977
|
+
'ask': undefined,
|
|
978
|
+
'askVolume': undefined,
|
|
979
|
+
'vwap': undefined,
|
|
980
|
+
'open': this.safeString2(ticker, 'open', 'o'),
|
|
981
|
+
'close': last,
|
|
982
|
+
'last': last,
|
|
983
|
+
'previousClose': undefined,
|
|
984
|
+
'change': undefined,
|
|
985
|
+
'percentage': undefined,
|
|
986
|
+
'average': undefined,
|
|
987
|
+
'baseVolume': this.safeString2(ticker, 'vol', 'v'),
|
|
988
|
+
'quoteVolume': undefined,
|
|
989
|
+
'markPrice': undefined,
|
|
990
|
+
'indexPrice': undefined,
|
|
991
|
+
'info': ticker,
|
|
992
|
+
}, market);
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* @method
|
|
996
|
+
* @name bydfi#fetchFundingRate
|
|
997
|
+
* @description fetch the current funding rate
|
|
998
|
+
* @see https://developers.bydfi.com/en/swap/market#recent-funding-rate
|
|
999
|
+
* @param {string} symbol unified market symbol
|
|
1000
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1001
|
+
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
|
|
1002
|
+
*/
|
|
1003
|
+
async fetchFundingRate(symbol, params = {}) {
|
|
1004
|
+
await this.loadMarkets();
|
|
1005
|
+
const market = this.market(symbol);
|
|
1006
|
+
const request = {
|
|
1007
|
+
'symbol': market['id'],
|
|
1008
|
+
};
|
|
1009
|
+
const response = await this.publicGetV1SwapMarketFundingRate(this.extend(request, params));
|
|
1010
|
+
//
|
|
1011
|
+
// {
|
|
1012
|
+
// "code": 200,
|
|
1013
|
+
// "message": "success",
|
|
1014
|
+
// "data": {
|
|
1015
|
+
// "symbol": "BTC-USDT",
|
|
1016
|
+
// "lastFundingRate": "0.0001",
|
|
1017
|
+
// "nextFundingTime": "1766188800000",
|
|
1018
|
+
// "time": "1766170665007"
|
|
1019
|
+
// },
|
|
1020
|
+
// "success": true
|
|
1021
|
+
// }
|
|
1022
|
+
//
|
|
1023
|
+
const data = this.safeDict(response, 'data');
|
|
1024
|
+
return this.parseFundingRate(data, market);
|
|
1025
|
+
}
|
|
1026
|
+
parseFundingRate(contract, market = undefined) {
|
|
1027
|
+
//
|
|
1028
|
+
// {
|
|
1029
|
+
// "symbol": "BTC-USDT",
|
|
1030
|
+
// "lastFundingRate": "0.0001",
|
|
1031
|
+
// "nextFundingTime": "1766188800000",
|
|
1032
|
+
// "time": "1766170665007"
|
|
1033
|
+
// }
|
|
1034
|
+
//
|
|
1035
|
+
const marketId = this.safeString(contract, 'symbol');
|
|
1036
|
+
const symbol = this.safeSymbol(marketId, market);
|
|
1037
|
+
const timestamp = this.safeInteger(contract, 'time');
|
|
1038
|
+
const nextFundingTimestamp = this.safeInteger(contract, 'nextFundingTime');
|
|
1039
|
+
return {
|
|
1040
|
+
'info': contract,
|
|
1041
|
+
'symbol': symbol,
|
|
1042
|
+
'markPrice': undefined,
|
|
1043
|
+
'indexPrice': undefined,
|
|
1044
|
+
'interestRate': undefined,
|
|
1045
|
+
'estimatedSettlePrice': undefined,
|
|
1046
|
+
'timestamp': timestamp,
|
|
1047
|
+
'datetime': this.iso8601(timestamp),
|
|
1048
|
+
'fundingRate': this.safeNumber(contract, 'lastFundingRate'),
|
|
1049
|
+
'fundingTimestamp': undefined,
|
|
1050
|
+
'fundingDatetime': undefined,
|
|
1051
|
+
'nextFundingRate': undefined,
|
|
1052
|
+
'nextFundingTimestamp': nextFundingTimestamp,
|
|
1053
|
+
'nextFundingDatetime': this.iso8601(nextFundingTimestamp),
|
|
1054
|
+
'previousFundingRate': undefined,
|
|
1055
|
+
'previousFundingTimestamp': undefined,
|
|
1056
|
+
'previousFundingDatetime': undefined,
|
|
1057
|
+
'interval': undefined,
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* @method
|
|
1062
|
+
* @name bydfi#fetchFundingRateHistory
|
|
1063
|
+
* @description fetches historical funding rate prices
|
|
1064
|
+
* @see https://developers.bydfi.com/en/swap/market#historical-funding-rates
|
|
1065
|
+
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
|
1066
|
+
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
|
1067
|
+
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/?id=funding-rate-history-structure} to fetch
|
|
1068
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1069
|
+
* @param {int} [params.until] timestamp in ms of the latest funding rate to fetch
|
|
1070
|
+
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/?id=funding-rate-history-structure}
|
|
1071
|
+
*/
|
|
1072
|
+
async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1073
|
+
if (symbol === undefined) {
|
|
1074
|
+
throw new ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
|
|
1075
|
+
}
|
|
1076
|
+
await this.loadMarkets();
|
|
1077
|
+
const market = this.market(symbol);
|
|
1078
|
+
const request = {
|
|
1079
|
+
'symbol': market['id'],
|
|
1080
|
+
};
|
|
1081
|
+
if (since !== undefined) {
|
|
1082
|
+
request['startTime'] = since;
|
|
1083
|
+
}
|
|
1084
|
+
if (limit !== undefined) {
|
|
1085
|
+
request['limit'] = limit;
|
|
1086
|
+
}
|
|
1087
|
+
let until = undefined;
|
|
1088
|
+
[until, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'until');
|
|
1089
|
+
if (until !== undefined) {
|
|
1090
|
+
request['endTime'] = until;
|
|
1091
|
+
}
|
|
1092
|
+
const response = await this.publicGetV1SwapMarketFundingRateHistory(this.extend(request, params));
|
|
1093
|
+
//
|
|
1094
|
+
// {
|
|
1095
|
+
// "code": 200,
|
|
1096
|
+
// "message": "success",
|
|
1097
|
+
// "data": [
|
|
1098
|
+
// {
|
|
1099
|
+
// "symbol": "ETH-USDT",
|
|
1100
|
+
// "fundingRate": "0.00000025",
|
|
1101
|
+
// "fundingTime": "1765584000000",
|
|
1102
|
+
// "markPrice": "3083.2"
|
|
1103
|
+
// }
|
|
1104
|
+
// ],
|
|
1105
|
+
// "success": true
|
|
1106
|
+
// }
|
|
1107
|
+
//
|
|
1108
|
+
const data = this.safeList(response, 'data', []);
|
|
1109
|
+
return this.parseFundingRateHistories(data, market, since, limit);
|
|
1110
|
+
}
|
|
1111
|
+
parseFundingRateHistory(contract, market = undefined) {
|
|
1112
|
+
//
|
|
1113
|
+
// {
|
|
1114
|
+
// "symbol": "ETH-USDT",
|
|
1115
|
+
// "fundingRate": "0.00000025",
|
|
1116
|
+
// "fundingTime": "1765584000000",
|
|
1117
|
+
// "markPrice": "3083.2"
|
|
1118
|
+
// }
|
|
1119
|
+
//
|
|
1120
|
+
const marketId = this.safeString(contract, 'symbol');
|
|
1121
|
+
const timestamp = this.safeInteger(contract, 'fundingTime');
|
|
1122
|
+
return {
|
|
1123
|
+
'info': contract,
|
|
1124
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
1125
|
+
'fundingRate': this.safeNumber(contract, 'fundingRate'),
|
|
1126
|
+
'timestamp': timestamp,
|
|
1127
|
+
'datetime': this.iso8601(timestamp),
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* @method
|
|
1132
|
+
* @name bydfi#createOrder
|
|
1133
|
+
* @description create a trade order
|
|
1134
|
+
* @see https://developers.bydfi.com/en/swap/trade#placing-an-order
|
|
1135
|
+
* @param {string} symbol unified symbol of the market to create an order in
|
|
1136
|
+
* @param {string} type 'market' or 'limit'
|
|
1137
|
+
* @param {string} side 'buy' or 'sell'
|
|
1138
|
+
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1139
|
+
* @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
1140
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1141
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1142
|
+
* @param {bool} [params.hedged] true for hedged mode, false for one way mode, default is false
|
|
1143
|
+
* @param {string} [params.clientOrderId] Custom order ID, must be unique for open orders
|
|
1144
|
+
* @param {string} [params.timeInForce] 'GTC' (Good Till Cancelled), 'FOK' (Fill Or Kill), 'IOC' (Immediate Or Cancel), 'PO' (Post Only)
|
|
1145
|
+
* @param {bool} [params.postOnly] true or false, whether the order is post-only
|
|
1146
|
+
* @param {bool} [params.reduceOnly] true or false, true or false whether the order is reduce-only
|
|
1147
|
+
* @param {float} [params.stopLossPrice] The price a stop loss order is triggered at
|
|
1148
|
+
* @param {float} [params.takeProfitPrice] The price a take profit order is triggered at
|
|
1149
|
+
* @param {float} [params.trailingTriggerPrice] the price to activate a trailing order, default uses the price argument or market price if price is not provided
|
|
1150
|
+
* @param {float} [params.trailingPercent] the percent to trail away from the current market price
|
|
1151
|
+
* @param {string} [params.triggerPriceType] 'MARK_PRICE' or 'CONTRACT_PRICE', default is 'CONTRACT_PRICE', the price type used to trigger stop orders
|
|
1152
|
+
* @param {bool} [params.closePosition] true or false, whether to close all positions after triggering, only supported in STOP_MARKET and TAKE_PROFIT_MARKET; not used with quantity;
|
|
1153
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1154
|
+
*/
|
|
1155
|
+
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1156
|
+
await this.loadMarkets();
|
|
1157
|
+
const market = this.market(symbol);
|
|
1158
|
+
let orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
1159
|
+
let wallet = 'W001';
|
|
1160
|
+
[wallet, params] = this.handleOptionAndParams(params, 'createOrder', 'wallet', wallet);
|
|
1161
|
+
orderRequest = this.extend(orderRequest, { 'wallet': wallet });
|
|
1162
|
+
const response = await this.privatePostV1SwapTradePlaceOrder(orderRequest);
|
|
1163
|
+
//
|
|
1164
|
+
// {
|
|
1165
|
+
// "code": 200,
|
|
1166
|
+
// "message": "success",
|
|
1167
|
+
// "data": {
|
|
1168
|
+
// "wallet": "W001",
|
|
1169
|
+
// "symbol": "ETH-USDT",
|
|
1170
|
+
// "orderId": "7408875768086683648",
|
|
1171
|
+
// "clientOrderId": "7408875768086683648",
|
|
1172
|
+
// "price": "1000",
|
|
1173
|
+
// "origQty": "10",
|
|
1174
|
+
// "avgPrice": null,
|
|
1175
|
+
// "executedQty": "0",
|
|
1176
|
+
// "orderType": "LIMIT",
|
|
1177
|
+
// "side": "BUY",
|
|
1178
|
+
// "status": "NEW",
|
|
1179
|
+
// "stopPrice": null,
|
|
1180
|
+
// "activatePrice": null,
|
|
1181
|
+
// "timeInForce": null,
|
|
1182
|
+
// "workingType": "CONTRACT_PRICE",
|
|
1183
|
+
// "positionSide": "BOTH",
|
|
1184
|
+
// "priceProtect": false,
|
|
1185
|
+
// "reduceOnly": false,
|
|
1186
|
+
// "closePosition": false,
|
|
1187
|
+
// "createTime": "1766413633367",
|
|
1188
|
+
// "updateTime": "1766413633367"
|
|
1189
|
+
// },
|
|
1190
|
+
// "success": true
|
|
1191
|
+
// }
|
|
1192
|
+
//
|
|
1193
|
+
const data = this.safeDict(response, 'data', {});
|
|
1194
|
+
return this.parseOrder(data, market);
|
|
1195
|
+
}
|
|
1196
|
+
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1197
|
+
const market = this.market(symbol);
|
|
1198
|
+
const request = {
|
|
1199
|
+
'symbol': market['id'],
|
|
1200
|
+
'side': side.toUpperCase(),
|
|
1201
|
+
// 'positionSide': STRING Position direction, not required in single position mode, default and can only be BOTH; required in dual position mode, and can only choose LONG or SHORT
|
|
1202
|
+
// 'type': STRING Order type LIMIT / MARKET / STOP / TAKE_PROFIT / STOP_MARKET / TAKE_PROFIT_MARKET / TRAILING_STOP_MARKET
|
|
1203
|
+
// 'reduceOnly': BOOL true, false; defaults to false in non-dual mode; not accepted in dual mode; not supported when using closePosition.
|
|
1204
|
+
// 'quantity': DECIMAL Order quantity, not supported with closePosition.
|
|
1205
|
+
// 'price': DECIMAL Order price
|
|
1206
|
+
// 'clientOrderId': STRING User-defined order number, must not be repeated in pending orders. If blank, the system will assign automatically
|
|
1207
|
+
// 'stopPrice': DECIMAL Trigger price, only required for STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET
|
|
1208
|
+
// 'closePosition': BOOL true, false; all positions closed after triggering, only supported in STOP_MARKET and TAKE_PROFIT_MARKET; not used with quantity; has a self-closing effect, not used with reduceOnly
|
|
1209
|
+
// 'activationPrice': DECIMAL Trailing stop activation price, required for TRAILING_STOP_MARKET, default to current market price upon order (supports different workingType)
|
|
1210
|
+
// 'callbackRate': DECIMAL Trailing stop callback rate, can range from [0.1, 5], where 1 represents 1%, only required for TRAILING_STOP_MARKET
|
|
1211
|
+
// 'timeInForce': STRING Validity method GTC / FOK / POST_ONLY / IOC / TRAILING_STOP
|
|
1212
|
+
// 'workingType': STRING stopPrice trigger type: MARK_PRICE(marking price), CONTRACT_PRICE(latest contract price). Default CONTRACT_PRICE
|
|
1213
|
+
};
|
|
1214
|
+
const stopLossPrice = this.safeString(params, 'stopLossPrice');
|
|
1215
|
+
const isStopLossOrder = (stopLossPrice !== undefined);
|
|
1216
|
+
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
|
|
1217
|
+
const isTakeProfitOrder = (takeProfitPrice !== undefined);
|
|
1218
|
+
const trailingPercent = this.safeString(params, 'trailingPercent');
|
|
1219
|
+
const isTailingStopOrder = (trailingPercent !== undefined);
|
|
1220
|
+
let stopPrice = undefined;
|
|
1221
|
+
if (isStopLossOrder || isTakeProfitOrder) {
|
|
1222
|
+
stopPrice = isStopLossOrder ? stopLossPrice : takeProfitPrice;
|
|
1223
|
+
params = this.omit(params, ['stopLossPrice', 'takeProfitPrice']);
|
|
1224
|
+
request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
1225
|
+
}
|
|
1226
|
+
else if (isTailingStopOrder) {
|
|
1227
|
+
params = this.omit(params, ['trailingPercent']);
|
|
1228
|
+
request['callbackRate'] = trailingPercent;
|
|
1229
|
+
let trailingTriggerPrice = this.numberToString(price);
|
|
1230
|
+
[trailingTriggerPrice, params] = this.handleParamString(params, 'trailingTriggerPrice', trailingTriggerPrice);
|
|
1231
|
+
if (trailingTriggerPrice !== undefined) {
|
|
1232
|
+
request['activationPrice'] = this.priceToPrecision(symbol, trailingTriggerPrice);
|
|
1233
|
+
params = this.omit(params, ['trailingTriggerPrice']);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
type = type.toUpperCase();
|
|
1237
|
+
const isMarketOrder = ((type === 'MARKET') || (type === 'STOP_MARKET') || (type === 'TAKE_PROFIT_MARKET') || (type === 'TRAILING_STOP_MARKET'));
|
|
1238
|
+
if (isMarketOrder) {
|
|
1239
|
+
if (type === 'MARKET') {
|
|
1240
|
+
if (isStopLossOrder) {
|
|
1241
|
+
type = 'STOP_MARKET';
|
|
1242
|
+
}
|
|
1243
|
+
else if (isTakeProfitOrder) {
|
|
1244
|
+
type = 'TAKE_PROFIT_MARKET';
|
|
1245
|
+
}
|
|
1246
|
+
else if (isTailingStopOrder) {
|
|
1247
|
+
type = 'TRAILING_STOP_MARKET';
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
else {
|
|
1252
|
+
if (price === undefined) {
|
|
1253
|
+
throw new ArgumentsRequired(this.id + ' createOrder() requires a price argument for a ' + type + ' order');
|
|
1254
|
+
}
|
|
1255
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
1256
|
+
if (isStopLossOrder) {
|
|
1257
|
+
type = 'STOP';
|
|
1258
|
+
}
|
|
1259
|
+
else if (isTakeProfitOrder) {
|
|
1260
|
+
type = 'TAKE_PROFIT';
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
request['type'] = type;
|
|
1264
|
+
let hedged = false;
|
|
1265
|
+
[hedged, params] = this.handleOptionAndParams(params, 'createOrder', 'hedged', hedged);
|
|
1266
|
+
const reduceOnly = this.safeBool(params, 'reduceOnly', false);
|
|
1267
|
+
if (hedged) {
|
|
1268
|
+
params = this.omit(params, 'reduceOnly');
|
|
1269
|
+
if (side === 'buy') {
|
|
1270
|
+
request['positionSide'] = reduceOnly ? 'SHORT' : 'LONG';
|
|
1271
|
+
}
|
|
1272
|
+
else if (side === 'sell') {
|
|
1273
|
+
request['positionSide'] = reduceOnly ? 'LONG' : 'SHORT';
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
const closePosition = this.safeBool(params, 'closePosition', false);
|
|
1277
|
+
if (!closePosition) {
|
|
1278
|
+
params = this.omit(params, 'closePosition');
|
|
1279
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
1280
|
+
}
|
|
1281
|
+
else if ((type !== 'STOP_MARKET') && (type !== 'TAKE_PROFIT_MARKET')) {
|
|
1282
|
+
throw new NotSupported(this.id + ' createOrder() closePosition is only supported for stopLoss and takeProfit market orders');
|
|
1283
|
+
}
|
|
1284
|
+
let timeInForce = this.handleTimeInForce(params);
|
|
1285
|
+
let postOnly = false;
|
|
1286
|
+
[postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'POST_ONLY', params);
|
|
1287
|
+
if (postOnly) {
|
|
1288
|
+
timeInForce = 'POST_ONLY';
|
|
1289
|
+
}
|
|
1290
|
+
if (timeInForce !== undefined) {
|
|
1291
|
+
request['timeInForce'] = timeInForce;
|
|
1292
|
+
params = this.omit(params, 'timeInForce');
|
|
1293
|
+
}
|
|
1294
|
+
if (isStopLossOrder || isTakeProfitOrder || isTailingStopOrder) {
|
|
1295
|
+
let workingType = 'CONTRACT_PRICE';
|
|
1296
|
+
[workingType, params] = this.handleOptionAndParams(params, 'createOrder', 'triggerPriceType', workingType);
|
|
1297
|
+
request['workingType'] = this.encodeWorkingType(workingType);
|
|
1298
|
+
}
|
|
1299
|
+
return this.extend(request, params);
|
|
1300
|
+
}
|
|
1301
|
+
encodeWorkingType(workingType) {
|
|
1302
|
+
const types = {
|
|
1303
|
+
'markPrice': 'MARK_PRICE',
|
|
1304
|
+
'mark': 'MARK_PRICE',
|
|
1305
|
+
'contractPrice': 'CONTRACT_PRICE',
|
|
1306
|
+
'contract': 'CONTRACT_PRICE',
|
|
1307
|
+
'last': 'CONTRACT_PRICE',
|
|
1308
|
+
};
|
|
1309
|
+
return this.safeString(types, workingType, workingType);
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* @method
|
|
1313
|
+
* @name bydfi#createOrders
|
|
1314
|
+
* @description create a list of trade orders
|
|
1315
|
+
* @see https://developers.bydfi.com/en/swap/trade#batch-order-placement
|
|
1316
|
+
* @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
|
|
1317
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1318
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1319
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1320
|
+
*/
|
|
1321
|
+
async createOrders(orders, params = {}) {
|
|
1322
|
+
await this.loadMarkets();
|
|
1323
|
+
const length = orders.length;
|
|
1324
|
+
if (length > 5) {
|
|
1325
|
+
throw new BadRequest(this.id + ' createOrders() accepts a maximum of 5 orders');
|
|
1326
|
+
}
|
|
1327
|
+
const ordersRequests = [];
|
|
1328
|
+
for (let i = 0; i < orders.length; i++) {
|
|
1329
|
+
const rawOrder = orders[i];
|
|
1330
|
+
const symbol = this.safeString(rawOrder, 'symbol');
|
|
1331
|
+
const type = this.safeString(rawOrder, 'type');
|
|
1332
|
+
const side = this.safeString(rawOrder, 'side');
|
|
1333
|
+
const amount = this.safeNumber(rawOrder, 'amount');
|
|
1334
|
+
const price = this.safeNumber(rawOrder, 'price');
|
|
1335
|
+
const orderParams = this.safeDict(rawOrder, 'params', {});
|
|
1336
|
+
const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, orderParams);
|
|
1337
|
+
ordersRequests.push(orderRequest);
|
|
1338
|
+
}
|
|
1339
|
+
let wallet = 'W001';
|
|
1340
|
+
[wallet, params] = this.handleOptionAndParams(params, 'createOrder', 'wallet', wallet);
|
|
1341
|
+
const request = {
|
|
1342
|
+
'wallet': wallet,
|
|
1343
|
+
'orders': ordersRequests,
|
|
1344
|
+
};
|
|
1345
|
+
const response = await this.privatePostV1SwapTradeBatchPlaceOrder(this.extend(request, params));
|
|
1346
|
+
const data = this.safeList(response, 'data', []);
|
|
1347
|
+
return this.parseOrders(data);
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* @method
|
|
1351
|
+
* @name bydfi#editOrder
|
|
1352
|
+
* @description edit a trade order
|
|
1353
|
+
* @see https://developers.bydfi.com/en/swap/trade#order-modification
|
|
1354
|
+
* @param {string} id order id (mandatory if params.clientOrderId is not provided)
|
|
1355
|
+
* @param {string} [symbol] unified symbol of the market to create an order in
|
|
1356
|
+
* @param {string} [type] not used by bydfi editOrder
|
|
1357
|
+
* @param {string} [side] 'buy' or 'sell'
|
|
1358
|
+
* @param {float} [amount] how much of the currency you want to trade in units of the base currency
|
|
1359
|
+
* @param {float} [price] the price for the order, in units of the quote currency, ignored in market orders
|
|
1360
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1361
|
+
* @param {string} [params.clientOrderId] a unique identifier for the order (could be alternative to id)
|
|
1362
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1363
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1364
|
+
*/
|
|
1365
|
+
async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
1366
|
+
await this.loadMarkets();
|
|
1367
|
+
const request = this.createEditOrderRequest(id, symbol, 'limit', side, amount, price, params);
|
|
1368
|
+
let wallet = 'W001';
|
|
1369
|
+
[wallet, params] = this.handleOptionAndParams(params, 'editOrder', 'wallet', wallet);
|
|
1370
|
+
request['wallet'] = wallet;
|
|
1371
|
+
const response = await this.privatePostV1SwapTradeEditOrder(request);
|
|
1372
|
+
const data = this.safeDict(response, 'data', {});
|
|
1373
|
+
return this.parseOrder(data);
|
|
1374
|
+
}
|
|
1375
|
+
/**
|
|
1376
|
+
* @method
|
|
1377
|
+
* @name bydfi#editOrders
|
|
1378
|
+
* @description edit a list of trade orders
|
|
1379
|
+
* @see https://developers.bydfi.com/en/swap/trade#batch-order-modification
|
|
1380
|
+
* @param {Array} orders list of orders to edit, each object should contain the parameters required by editOrder, namely id, symbol, amount, price and params
|
|
1381
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1382
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1383
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1384
|
+
*/
|
|
1385
|
+
async editOrders(orders, params = {}) {
|
|
1386
|
+
await this.loadMarkets();
|
|
1387
|
+
const length = orders.length;
|
|
1388
|
+
if (length > 5) {
|
|
1389
|
+
throw new BadRequest(this.id + ' editOrders() accepts a maximum of 5 orders');
|
|
1390
|
+
}
|
|
1391
|
+
const ordersRequests = [];
|
|
1392
|
+
for (let i = 0; i < orders.length; i++) {
|
|
1393
|
+
const rawOrder = orders[i];
|
|
1394
|
+
const id = this.safeString(rawOrder, 'id');
|
|
1395
|
+
const symbol = this.safeString(rawOrder, 'symbol');
|
|
1396
|
+
const side = this.safeString(rawOrder, 'side');
|
|
1397
|
+
const amount = this.safeNumber(rawOrder, 'amount');
|
|
1398
|
+
const price = this.safeNumber(rawOrder, 'price');
|
|
1399
|
+
const orderParams = this.safeDict(rawOrder, 'params', {});
|
|
1400
|
+
const orderRequest = this.createEditOrderRequest(id, symbol, 'limit', side, amount, price, orderParams);
|
|
1401
|
+
ordersRequests.push(orderRequest);
|
|
1402
|
+
}
|
|
1403
|
+
let wallet = 'W001';
|
|
1404
|
+
[wallet, params] = this.handleOptionAndParams(params, 'editOrder', 'wallet', wallet);
|
|
1405
|
+
const request = {
|
|
1406
|
+
'wallet': wallet,
|
|
1407
|
+
'editOrders': ordersRequests,
|
|
1408
|
+
};
|
|
1409
|
+
const response = await this.privatePostV1SwapTradeBatchEditOrder(this.extend(request, params));
|
|
1410
|
+
const data = this.safeList(response, 'data', []);
|
|
1411
|
+
return this.parseOrders(data);
|
|
1412
|
+
}
|
|
1413
|
+
createEditOrderRequest(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
|
|
1414
|
+
const clientOrderId = this.safeString(params, 'clientOrderId');
|
|
1415
|
+
const request = {};
|
|
1416
|
+
if ((id === undefined) && (clientOrderId === undefined)) {
|
|
1417
|
+
throw new ArgumentsRequired(this.id + ' editOrder() requires an id argument or a clientOrderId parameter');
|
|
1418
|
+
}
|
|
1419
|
+
else if (id !== undefined) {
|
|
1420
|
+
request['orderId'] = id;
|
|
1421
|
+
}
|
|
1422
|
+
const market = this.market(symbol);
|
|
1423
|
+
request['symbol'] = market['id'];
|
|
1424
|
+
if (side !== undefined) {
|
|
1425
|
+
request['side'] = side.toUpperCase();
|
|
1426
|
+
}
|
|
1427
|
+
if (amount !== undefined) {
|
|
1428
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
1429
|
+
}
|
|
1430
|
+
if (price !== undefined) {
|
|
1431
|
+
request['price'] = this.priceToPrecision(symbol, price);
|
|
1432
|
+
}
|
|
1433
|
+
return this.extend(request, params);
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* @method
|
|
1437
|
+
* @name bydfi#cancelAllOrders
|
|
1438
|
+
* @description cancel all open orders in a market
|
|
1439
|
+
* @see https://developers.bydfi.com/en/swap/trade#complete-order-cancellation
|
|
1440
|
+
* @param {string} symbol unified market symbol of the market to cancel orders in
|
|
1441
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1442
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1443
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1444
|
+
*/
|
|
1445
|
+
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1446
|
+
if (symbol === undefined) {
|
|
1447
|
+
throw new ArgumentsRequired(this.id + ' cancelAllOrders() requires a symbol argument');
|
|
1448
|
+
}
|
|
1449
|
+
await this.loadMarkets();
|
|
1450
|
+
const market = this.market(symbol);
|
|
1451
|
+
let wallet = 'W001';
|
|
1452
|
+
[wallet, params] = this.handleOptionAndParams(params, 'cancelAllOrders', 'wallet', wallet);
|
|
1453
|
+
const request = {
|
|
1454
|
+
'symbol': market['id'],
|
|
1455
|
+
'wallet': wallet,
|
|
1456
|
+
};
|
|
1457
|
+
const response = await this.privatePostV1SwapTradeCancelAllOrder(this.extend(request, params));
|
|
1458
|
+
//
|
|
1459
|
+
// {
|
|
1460
|
+
// "code": 200,
|
|
1461
|
+
// "message": "success",
|
|
1462
|
+
// "data": [
|
|
1463
|
+
// {
|
|
1464
|
+
// "wallet": "W001",
|
|
1465
|
+
// "symbol": "ETH-USDT",
|
|
1466
|
+
// "orderId": "7408875768086683648",
|
|
1467
|
+
// "clientOrderId": "7408875768086683648",
|
|
1468
|
+
// "price": "1000",
|
|
1469
|
+
// "origQty": "10",
|
|
1470
|
+
// "avgPrice": "0",
|
|
1471
|
+
// "executedQty": "0",
|
|
1472
|
+
// "orderType": "LIMIT",
|
|
1473
|
+
// "side": "BUY",
|
|
1474
|
+
// "status": "CANCELED",
|
|
1475
|
+
// "stopPrice": null,
|
|
1476
|
+
// "activatePrice": null,
|
|
1477
|
+
// "timeInForce": null,
|
|
1478
|
+
// "workingType": "CONTRACT_PRICE",
|
|
1479
|
+
// "positionSide": "BOTH",
|
|
1480
|
+
// "priceProtect": false,
|
|
1481
|
+
// "reduceOnly": false,
|
|
1482
|
+
// "closePosition": false,
|
|
1483
|
+
// "createTime": "1766413633367",
|
|
1484
|
+
// "updateTime": "1766413633370"
|
|
1485
|
+
// }
|
|
1486
|
+
// ],
|
|
1487
|
+
// "success": true
|
|
1488
|
+
// }
|
|
1489
|
+
//
|
|
1490
|
+
const data = this.safeList(response, 'data', []);
|
|
1491
|
+
return this.parseOrders(data, market);
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* @method
|
|
1495
|
+
* @name bydfi#fetchOpenOrders
|
|
1496
|
+
* @description fetch all unfilled currently open orders
|
|
1497
|
+
* @see https://developers.bydfi.com/en/swap/trade#pending-order-query
|
|
1498
|
+
* @see https://developers.bydfi.com/en/swap/trade#planned-order-query
|
|
1499
|
+
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1500
|
+
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1501
|
+
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1502
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1503
|
+
* @param {bool} [params.trigger] true or false, whether to fetch conditional orders only
|
|
1504
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1505
|
+
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1506
|
+
*/
|
|
1507
|
+
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1508
|
+
if (symbol === undefined) {
|
|
1509
|
+
throw new ArgumentsRequired(this.id + ' fetchOpenOrders() requires a symbol argument');
|
|
1510
|
+
}
|
|
1511
|
+
await this.loadMarkets();
|
|
1512
|
+
const market = this.market(symbol);
|
|
1513
|
+
let wallet = 'W001';
|
|
1514
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'wallet', wallet);
|
|
1515
|
+
const request = {
|
|
1516
|
+
'symbol': market['id'],
|
|
1517
|
+
'wallet': wallet,
|
|
1518
|
+
};
|
|
1519
|
+
let response = undefined;
|
|
1520
|
+
let trigger = false;
|
|
1521
|
+
[trigger, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'trigger', trigger);
|
|
1522
|
+
if (!trigger) {
|
|
1523
|
+
//
|
|
1524
|
+
// {
|
|
1525
|
+
// "code": 200,
|
|
1526
|
+
// "message": "success",
|
|
1527
|
+
// "data": [
|
|
1528
|
+
// {
|
|
1529
|
+
// "wallet": "W001",
|
|
1530
|
+
// "symbol": "ETH-USDC",
|
|
1531
|
+
// "orderId": "7408896083240091648",
|
|
1532
|
+
// "clientOrderId": "7408896083240091648",
|
|
1533
|
+
// "price": "999",
|
|
1534
|
+
// "origQty": "1",
|
|
1535
|
+
// "avgPrice": "0",
|
|
1536
|
+
// "executedQty": "0",
|
|
1537
|
+
// "orderType": "LIMIT",
|
|
1538
|
+
// "side": "BUY",
|
|
1539
|
+
// "status": "NEW",
|
|
1540
|
+
// "stopPrice": null,
|
|
1541
|
+
// "activatePrice": null,
|
|
1542
|
+
// "timeInForce": null,
|
|
1543
|
+
// "workingType": "CONTRACT_PRICE",
|
|
1544
|
+
// "positionSide": "BOTH",
|
|
1545
|
+
// "priceProtect": false,
|
|
1546
|
+
// "reduceOnly": false,
|
|
1547
|
+
// "closePosition": false,
|
|
1548
|
+
// "createTime": "1766418476877",
|
|
1549
|
+
// "updateTime": "1766418476880"
|
|
1550
|
+
// }
|
|
1551
|
+
// ],
|
|
1552
|
+
// "success": true
|
|
1553
|
+
// }
|
|
1554
|
+
//
|
|
1555
|
+
response = await this.privateGetV1SwapTradeOpenOrder(this.extend(request, params));
|
|
1556
|
+
}
|
|
1557
|
+
else {
|
|
1558
|
+
response = await this.privateGetV1SwapTradePlanOrder(this.extend(request, params));
|
|
1559
|
+
}
|
|
1560
|
+
const data = this.safeList(response, 'data', []);
|
|
1561
|
+
return this.parseOrders(data, market, since, limit);
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* @method
|
|
1565
|
+
* @name bydfi#fetchOpenOrder
|
|
1566
|
+
* @description fetch an open order by the id
|
|
1567
|
+
* @see https://developers.bydfi.com/en/swap/trade#pending-order-query
|
|
1568
|
+
* @see https://developers.bydfi.com/en/swap/trade#planned-order-query
|
|
1569
|
+
* @param {string} id order id (mandatory if params.clientOrderId is not provided)
|
|
1570
|
+
* @param {string} symbol unified market symbol
|
|
1571
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1572
|
+
* @param {bool} [params.trigger] true or false, whether to fetch conditional orders only
|
|
1573
|
+
* @param {string} [params.clientOrderId] a unique identifier for the order (could be alternative to id)
|
|
1574
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1575
|
+
* @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1576
|
+
*/
|
|
1577
|
+
async fetchOpenOrder(id, symbol = undefined, params = {}) {
|
|
1578
|
+
if (symbol === undefined) {
|
|
1579
|
+
throw new ArgumentsRequired(this.id + ' fetchOpenOrder() requires a symbol argument');
|
|
1580
|
+
}
|
|
1581
|
+
await this.loadMarkets();
|
|
1582
|
+
const market = this.market(symbol);
|
|
1583
|
+
const request = {
|
|
1584
|
+
'symbol': market['id'],
|
|
1585
|
+
};
|
|
1586
|
+
const clientOrderId = this.safeString(params, 'clientOrderId');
|
|
1587
|
+
if ((id === undefined) && (clientOrderId === undefined)) {
|
|
1588
|
+
throw new ArgumentsRequired(this.id + ' fetchOpenOrder() requires an id argument or a clientOrderId parameter');
|
|
1589
|
+
}
|
|
1590
|
+
else if (id !== undefined) {
|
|
1591
|
+
request['orderId'] = id;
|
|
1592
|
+
}
|
|
1593
|
+
let wallet = 'W001';
|
|
1594
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchOpenOrder', 'wallet', wallet);
|
|
1595
|
+
request['wallet'] = wallet;
|
|
1596
|
+
let response = undefined;
|
|
1597
|
+
let trigger = false;
|
|
1598
|
+
[trigger, params] = this.handleOptionAndParams(params, 'fetchOpenOrder', 'trigger', trigger);
|
|
1599
|
+
if (!trigger) {
|
|
1600
|
+
response = await this.privateGetV1SwapTradeOpenOrder(this.extend(request, params));
|
|
1601
|
+
}
|
|
1602
|
+
else {
|
|
1603
|
+
response = await this.privateGetV1SwapTradePlanOrder(this.extend(request, params));
|
|
1604
|
+
}
|
|
1605
|
+
const data = this.safeList(response, 'data', []);
|
|
1606
|
+
const order = this.safeDict(data, 0, {});
|
|
1607
|
+
return this.parseOrder(order, market);
|
|
1608
|
+
}
|
|
1609
|
+
/**
|
|
1610
|
+
* @method
|
|
1611
|
+
* @name bydfi#fetchCanceledAndClosedOrders
|
|
1612
|
+
* @description fetches information on multiple canceled and closed orders made by the user
|
|
1613
|
+
* @see https://developers.bydfi.com/en/swap/trade#historical-orders-query
|
|
1614
|
+
* @param {string} symbol unified market symbol of the closed orders
|
|
1615
|
+
* @param {int} [since] timestamp in ms of the earliest order
|
|
1616
|
+
* @param {int} [limit] the max number of closed orders to return
|
|
1617
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1618
|
+
* @param {int} [params.until] timestamp in ms of the latest order
|
|
1619
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
1620
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet
|
|
1621
|
+
* @param {string} [params.orderType] order type ('LIMIT', 'MARKET', 'LIQ', 'LIMIT_CLOSE', 'MARKET_CLOSE', 'STOP', 'TAKE_PROFIT', 'STOP_MARKET', 'TAKE_PROFIT_MARKET' or 'TRAILING_STOP_MARKET')
|
|
1622
|
+
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
|
|
1623
|
+
*/
|
|
1624
|
+
async fetchCanceledAndClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1625
|
+
await this.loadMarkets();
|
|
1626
|
+
const paginate = this.safeBool(params, 'paginate', false);
|
|
1627
|
+
if (paginate) {
|
|
1628
|
+
const maxLimit = 500;
|
|
1629
|
+
params = this.omit(params, 'paginate');
|
|
1630
|
+
params = this.extend(params, { 'paginationDirection': 'backward' });
|
|
1631
|
+
const paginatedResponse = await this.fetchPaginatedCallDynamic('fetchCanceledAndClosedOrders', symbol, since, limit, params, maxLimit, true);
|
|
1632
|
+
return this.sortBy(paginatedResponse, 'timestamp');
|
|
1633
|
+
}
|
|
1634
|
+
let contractType = 'FUTURE';
|
|
1635
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchCanceledAndClosedOrders', 'contractType', contractType);
|
|
1636
|
+
const request = {
|
|
1637
|
+
'contractType': contractType,
|
|
1638
|
+
};
|
|
1639
|
+
let market = undefined;
|
|
1640
|
+
if (symbol !== undefined) {
|
|
1641
|
+
market = this.market(symbol);
|
|
1642
|
+
request['symbol'] = market['id'];
|
|
1643
|
+
}
|
|
1644
|
+
params = this.handleSinceAndUntil('fetchCanceledAndClosedOrders', since, params);
|
|
1645
|
+
if (limit !== undefined) {
|
|
1646
|
+
request['limit'] = limit;
|
|
1647
|
+
}
|
|
1648
|
+
const response = await this.privateGetV1SwapTradeHistoryOrder(this.extend(request, params));
|
|
1649
|
+
//
|
|
1650
|
+
// {
|
|
1651
|
+
// "code": 200,
|
|
1652
|
+
// "message": "success",
|
|
1653
|
+
// "data": [
|
|
1654
|
+
// {
|
|
1655
|
+
// "orderId": "7408919189505597440",
|
|
1656
|
+
// "orderType": "MARKET",
|
|
1657
|
+
// "symbol": "ETH-USDC",
|
|
1658
|
+
// "origQty": "1",
|
|
1659
|
+
// "side": "BUY",
|
|
1660
|
+
// "positionSide": "BOTH",
|
|
1661
|
+
// "positionAvgPrice": null,
|
|
1662
|
+
// "positionVolume": null,
|
|
1663
|
+
// "positionType": null,
|
|
1664
|
+
// "reduceOnly": false,
|
|
1665
|
+
// "closePosition": false,
|
|
1666
|
+
// "action": null,
|
|
1667
|
+
// "price": "3032.45",
|
|
1668
|
+
// "avgPrice": "3032.45",
|
|
1669
|
+
// "brkPrice": null,
|
|
1670
|
+
// "dealVolume": null,
|
|
1671
|
+
// "status": "2",
|
|
1672
|
+
// "wallet": "W001",
|
|
1673
|
+
// "alias": null,
|
|
1674
|
+
// "contractId": null,
|
|
1675
|
+
// "mtime": "1766423985842",
|
|
1676
|
+
// "ctime": "1766423985840",
|
|
1677
|
+
// "fixedPrice": null,
|
|
1678
|
+
// "direction": null,
|
|
1679
|
+
// "triggerPrice": null,
|
|
1680
|
+
// "priceType": null,
|
|
1681
|
+
// "basePrecision": "8",
|
|
1682
|
+
// "baseShowPrecision": "2",
|
|
1683
|
+
// "strategyType": null,
|
|
1684
|
+
// "leverageLevel": 1,
|
|
1685
|
+
// "marginType": "CROSS",
|
|
1686
|
+
// "remark": null,
|
|
1687
|
+
// "callbackRate": null,
|
|
1688
|
+
// "activationPrice": null
|
|
1689
|
+
// }
|
|
1690
|
+
// ],
|
|
1691
|
+
// "success": true
|
|
1692
|
+
// }
|
|
1693
|
+
//
|
|
1694
|
+
const data = this.safeList(response, 'data', []);
|
|
1695
|
+
return this.parseOrders(data, market, since, limit);
|
|
1696
|
+
}
|
|
1697
|
+
handleSinceAndUntil(methodName, since = undefined, params = {}) {
|
|
1698
|
+
let until = undefined;
|
|
1699
|
+
[until, params] = this.handleOptionAndParams2(params, methodName, 'until', 'endTime');
|
|
1700
|
+
const now = this.milliseconds();
|
|
1701
|
+
const sevenDays = 7 * 24 * 60 * 60 * 1000; // the maximum range is 7 days
|
|
1702
|
+
let startTime = since;
|
|
1703
|
+
if (startTime === undefined) {
|
|
1704
|
+
if (until === undefined) {
|
|
1705
|
+
// both since and until are undefined
|
|
1706
|
+
startTime = now - sevenDays;
|
|
1707
|
+
until = now;
|
|
1708
|
+
}
|
|
1709
|
+
else {
|
|
1710
|
+
// since is undefined but until is defined
|
|
1711
|
+
startTime = until - sevenDays;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
else if (until === undefined) {
|
|
1715
|
+
// until is undefined but since is defined
|
|
1716
|
+
const delta = now - startTime;
|
|
1717
|
+
if (delta > sevenDays) {
|
|
1718
|
+
until = startTime + sevenDays;
|
|
1719
|
+
}
|
|
1720
|
+
else {
|
|
1721
|
+
until = now;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
const request = {
|
|
1725
|
+
'startTime': startTime,
|
|
1726
|
+
'endTime': until,
|
|
1727
|
+
};
|
|
1728
|
+
return this.extend(request, params);
|
|
1729
|
+
}
|
|
1730
|
+
parseOrder(order, market = undefined) {
|
|
1731
|
+
//
|
|
1732
|
+
// createOrder, fetchOpenOrders, fetchOpenOrder
|
|
1733
|
+
// {
|
|
1734
|
+
// "wallet": "W001",
|
|
1735
|
+
// "symbol": "ETH-USDT",
|
|
1736
|
+
// "orderId": "7408875768086683648",
|
|
1737
|
+
// "clientOrderId": "7408875768086683648",
|
|
1738
|
+
// "price": "1000",
|
|
1739
|
+
// "origQty": "10",
|
|
1740
|
+
// "avgPrice": "0",
|
|
1741
|
+
// "executedQty": "0",
|
|
1742
|
+
// "orderType": "LIMIT",
|
|
1743
|
+
// "side": "BUY",
|
|
1744
|
+
// "status": "CANCELED",
|
|
1745
|
+
// "stopPrice": null,
|
|
1746
|
+
// "activatePrice": null,
|
|
1747
|
+
// "timeInForce": null,
|
|
1748
|
+
// "workingType": "CONTRACT_PRICE",
|
|
1749
|
+
// "positionSide": "BOTH",
|
|
1750
|
+
// "priceProtect": false,
|
|
1751
|
+
// "reduceOnly": false,
|
|
1752
|
+
// "closePosition": false,
|
|
1753
|
+
// "createTime": "1766413633367",
|
|
1754
|
+
// "updateTime": "1766413633370"
|
|
1755
|
+
// }
|
|
1756
|
+
//
|
|
1757
|
+
// fetchCanceledAndClosedOrders
|
|
1758
|
+
// {
|
|
1759
|
+
// "orderId": "7408919189505597440",
|
|
1760
|
+
// "orderType": "MARKET",
|
|
1761
|
+
// "symbol": "ETH-USDC",
|
|
1762
|
+
// "origQty": "1",
|
|
1763
|
+
// "side": "BUY",
|
|
1764
|
+
// "positionSide": "BOTH",
|
|
1765
|
+
// "positionAvgPrice": null,
|
|
1766
|
+
// "positionVolume": null,
|
|
1767
|
+
// "positionType": null,
|
|
1768
|
+
// "reduceOnly": false,
|
|
1769
|
+
// "closePosition": false,
|
|
1770
|
+
// "action": null,
|
|
1771
|
+
// "price": "3032.45",
|
|
1772
|
+
// "avgPrice": "3032.45",
|
|
1773
|
+
// "brkPrice": null,
|
|
1774
|
+
// "dealVolume": null,
|
|
1775
|
+
// "status": "2",
|
|
1776
|
+
// "wallet": "W001",
|
|
1777
|
+
// "alias": null,
|
|
1778
|
+
// "contractId": null,
|
|
1779
|
+
// "mtime": "1766423985842",
|
|
1780
|
+
// "ctime": "1766423985840",
|
|
1781
|
+
// "fixedPrice": null,
|
|
1782
|
+
// "direction": null,
|
|
1783
|
+
// "triggerPrice": null,
|
|
1784
|
+
// "priceType": null,
|
|
1785
|
+
// "basePrecision": "8",
|
|
1786
|
+
// "baseShowPrecision": "2",
|
|
1787
|
+
// "strategyType": null,
|
|
1788
|
+
// "leverageLevel": 1,
|
|
1789
|
+
// "marginType": "CROSS",
|
|
1790
|
+
// "remark": null,
|
|
1791
|
+
// "callbackRate": null,
|
|
1792
|
+
// "activationPrice": null
|
|
1793
|
+
// }
|
|
1794
|
+
//
|
|
1795
|
+
const marketId = this.safeString(order, 'symbol');
|
|
1796
|
+
market = this.safeMarket(marketId, market);
|
|
1797
|
+
const timestamp = this.safeInteger2(order, 'createTime', 'ctime');
|
|
1798
|
+
const rawType = this.safeString(order, 'orderType');
|
|
1799
|
+
const stopPrice = this.safeStringN(order, ['stopPrice', 'activatePrice', 'triggerPrice']);
|
|
1800
|
+
const isStopLossOrder = (rawType === 'STOP') || (rawType === 'STOP_MARKET') || (rawType === 'TRAILING_STOP_MARKET');
|
|
1801
|
+
const isTakeProfitOrder = (rawType === 'TAKE_PROFIT') || (rawType === 'TAKE_PROFIT_MARKET');
|
|
1802
|
+
const rawTimeInForce = this.safeString(order, 'timeInForce');
|
|
1803
|
+
const timeInForce = this.parseOrderTimeInForce(rawTimeInForce);
|
|
1804
|
+
let postOnly = undefined;
|
|
1805
|
+
if (timeInForce === 'PO') {
|
|
1806
|
+
postOnly = true;
|
|
1807
|
+
}
|
|
1808
|
+
const rawStatus = this.safeString(order, 'status');
|
|
1809
|
+
const fee = {};
|
|
1810
|
+
const quoteFee = this.safeNumber(order, 'quoteFee');
|
|
1811
|
+
if (quoteFee !== undefined) {
|
|
1812
|
+
fee['cost'] = quoteFee;
|
|
1813
|
+
fee['currency'] = market['quote'];
|
|
1814
|
+
}
|
|
1815
|
+
return this.safeOrder({
|
|
1816
|
+
'info': order,
|
|
1817
|
+
'id': this.safeString(order, 'orderId'),
|
|
1818
|
+
'clientOrderId': this.safeString(order, 'clientOrderId'),
|
|
1819
|
+
'timestamp': timestamp,
|
|
1820
|
+
'datetime': this.iso8601(timestamp),
|
|
1821
|
+
'lastTradeTimestamp': undefined,
|
|
1822
|
+
'lastUpdateTimestamp': this.safeInteger2(order, 'updateTime', 'mtime'),
|
|
1823
|
+
'status': this.parseOrderStatus(rawStatus),
|
|
1824
|
+
'symbol': market['symbol'],
|
|
1825
|
+
'type': this.parseOrderType(rawType),
|
|
1826
|
+
'timeInForce': timeInForce,
|
|
1827
|
+
'postOnly': postOnly,
|
|
1828
|
+
'reduceOnly': this.safeBool(order, 'reduceOnly'),
|
|
1829
|
+
'side': this.safeStringLower(order, 'side'),
|
|
1830
|
+
'price': this.safeString(order, 'price'),
|
|
1831
|
+
'triggerPrice': stopPrice,
|
|
1832
|
+
'stopLossPrice': isStopLossOrder ? stopPrice : undefined,
|
|
1833
|
+
'takeProfitPrice': isTakeProfitOrder ? stopPrice : undefined,
|
|
1834
|
+
'amount': this.safeString(order, 'origQty'),
|
|
1835
|
+
'filled': this.safeString(order, 'executedQty'),
|
|
1836
|
+
'remaining': undefined,
|
|
1837
|
+
'cost': undefined,
|
|
1838
|
+
'trades': undefined,
|
|
1839
|
+
'fee': fee,
|
|
1840
|
+
'average': this.omitZero(this.safeString(order, 'avgPrice')),
|
|
1841
|
+
}, market);
|
|
1842
|
+
}
|
|
1843
|
+
parseOrderType(type) {
|
|
1844
|
+
const types = {
|
|
1845
|
+
'LIMIT': 'limit',
|
|
1846
|
+
'MARKET': 'market',
|
|
1847
|
+
'STOP': 'limit',
|
|
1848
|
+
'STOP_MARKET': 'market',
|
|
1849
|
+
'TAKE_PROFIT': 'limit',
|
|
1850
|
+
'TAKE_PROFIT_MARKET': 'market',
|
|
1851
|
+
'TRAILING_STOP_MARKET': 'market',
|
|
1852
|
+
};
|
|
1853
|
+
return this.safeString(types, type, type);
|
|
1854
|
+
}
|
|
1855
|
+
parseOrderTimeInForce(timeInForce) {
|
|
1856
|
+
const timeInForces = {
|
|
1857
|
+
'GTC': 'GTC',
|
|
1858
|
+
'FOK': 'FOK',
|
|
1859
|
+
'IOC': 'IOC',
|
|
1860
|
+
'POST_ONLY': 'PO',
|
|
1861
|
+
'TRAILING_STOP': 'IOC',
|
|
1862
|
+
};
|
|
1863
|
+
return this.safeString(timeInForces, timeInForce, timeInForce);
|
|
1864
|
+
}
|
|
1865
|
+
parseOrderStatus(status) {
|
|
1866
|
+
const statuses = {
|
|
1867
|
+
'NEW': 'open',
|
|
1868
|
+
'PARTIALLY_FILLED': 'open',
|
|
1869
|
+
'FILLED': 'closed',
|
|
1870
|
+
'EXPIRED': 'canceled',
|
|
1871
|
+
'PART_FILLED_CANCELLED': 'canceled',
|
|
1872
|
+
'CANCELED': 'canceled',
|
|
1873
|
+
'2': 'closed',
|
|
1874
|
+
'4': 'canceled',
|
|
1875
|
+
};
|
|
1876
|
+
return this.safeString(statuses, status, status);
|
|
1877
|
+
}
|
|
1878
|
+
/**
|
|
1879
|
+
* @method
|
|
1880
|
+
* @name bydfi#setLeverage
|
|
1881
|
+
* @description set the level of leverage for a market
|
|
1882
|
+
* @see https://developers.bydfi.com/en/swap/trade#set-leverage-for-single-trading-pair
|
|
1883
|
+
* @param {float} leverage the rate of leverage
|
|
1884
|
+
* @param {string} symbol unified market symbol
|
|
1885
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1886
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1887
|
+
* @returns {object} response from the exchange
|
|
1888
|
+
*/
|
|
1889
|
+
async setLeverage(leverage, symbol = undefined, params = {}) {
|
|
1890
|
+
if (symbol === undefined) {
|
|
1891
|
+
throw new ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
|
|
1892
|
+
}
|
|
1893
|
+
await this.loadMarkets();
|
|
1894
|
+
const market = this.market(symbol);
|
|
1895
|
+
let wallet = 'W001';
|
|
1896
|
+
[wallet, params] = this.handleOptionAndParams(params, 'setLeverage', 'wallet', wallet);
|
|
1897
|
+
const request = {
|
|
1898
|
+
'symbol': market['id'],
|
|
1899
|
+
'leverage': leverage,
|
|
1900
|
+
'wallet': wallet,
|
|
1901
|
+
};
|
|
1902
|
+
const response = await this.privatePostV1SwapTradeLeverage(this.extend(request, params));
|
|
1903
|
+
const data = this.safeDict(response, 'data', {});
|
|
1904
|
+
return data;
|
|
1905
|
+
}
|
|
1906
|
+
/**
|
|
1907
|
+
* @method
|
|
1908
|
+
* @name bydfi#fetchLeverage
|
|
1909
|
+
* @description fetch the set leverage for a market
|
|
1910
|
+
* @see https://developers.bydfi.com/en/swap/trade#get-leverage-for-single-trading-pair
|
|
1911
|
+
* @param {string} symbol unified market symbol
|
|
1912
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1913
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
1914
|
+
* @returns {object} a [leverage structure]{@link https://docs.ccxt.com/?id=leverage-structure}
|
|
1915
|
+
*/
|
|
1916
|
+
async fetchLeverage(symbol, params = {}) {
|
|
1917
|
+
if (symbol === undefined) {
|
|
1918
|
+
throw new ArgumentsRequired(this.id + ' fetchLeverage() requires a symbol argument');
|
|
1919
|
+
}
|
|
1920
|
+
await this.loadMarkets();
|
|
1921
|
+
const market = this.market(symbol);
|
|
1922
|
+
let wallet = 'W001';
|
|
1923
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchLeverage', 'wallet', wallet);
|
|
1924
|
+
const request = {
|
|
1925
|
+
'symbol': market['id'],
|
|
1926
|
+
'wallet': wallet,
|
|
1927
|
+
};
|
|
1928
|
+
const response = await this.privateGetV1SwapTradeLeverage(this.extend(request, params));
|
|
1929
|
+
//
|
|
1930
|
+
// {
|
|
1931
|
+
// "code": 200,
|
|
1932
|
+
// "message": "success",
|
|
1933
|
+
// "data": {
|
|
1934
|
+
// "symbol": "ETH-USDC",
|
|
1935
|
+
// "leverage": 1,
|
|
1936
|
+
// "maxNotionalValue": "100000000"
|
|
1937
|
+
// },
|
|
1938
|
+
// "success": true
|
|
1939
|
+
// }
|
|
1940
|
+
//
|
|
1941
|
+
const data = this.safeDict(response, 'data', {});
|
|
1942
|
+
return this.parseLeverage(data, market);
|
|
1943
|
+
}
|
|
1944
|
+
parseLeverage(leverage, market = undefined) {
|
|
1945
|
+
const marketId = this.safeString(leverage, 'symbol');
|
|
1946
|
+
return {
|
|
1947
|
+
'info': leverage,
|
|
1948
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
1949
|
+
'marginMode': undefined,
|
|
1950
|
+
'longLeverage': this.safeInteger(leverage, 'leverage'),
|
|
1951
|
+
'shortLeverage': this.safeInteger(leverage, 'leverage'),
|
|
1952
|
+
};
|
|
1953
|
+
}
|
|
1954
|
+
/**
|
|
1955
|
+
* @method
|
|
1956
|
+
* @name bydfi#fetchPositions
|
|
1957
|
+
* @description fetch all open positions
|
|
1958
|
+
* @see https://developers.bydfi.com/en/swap/trade#positions-query
|
|
1959
|
+
* @param {string[]} [symbols] list of unified market symbols
|
|
1960
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1961
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
1962
|
+
* @param {string} [params.settleCoin] the settlement currency (USDT or USDC or USD)
|
|
1963
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
|
|
1964
|
+
*/
|
|
1965
|
+
async fetchPositions(symbols = undefined, params = {}) {
|
|
1966
|
+
await this.loadMarkets();
|
|
1967
|
+
let contractType = 'FUTURE';
|
|
1968
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchPositions', 'contractType', contractType);
|
|
1969
|
+
const request = {
|
|
1970
|
+
'contractType': contractType,
|
|
1971
|
+
};
|
|
1972
|
+
const response = await this.privateGetV1SwapTradePositions(this.extend(request, params));
|
|
1973
|
+
//
|
|
1974
|
+
// {
|
|
1975
|
+
// "code": 200,
|
|
1976
|
+
// "message": "success",
|
|
1977
|
+
// "data": [
|
|
1978
|
+
// {
|
|
1979
|
+
// "symbol": "ETH-USDC",
|
|
1980
|
+
// "side": "BUY",
|
|
1981
|
+
// "volume": "0.001",
|
|
1982
|
+
// "avgPrice": "3032.45",
|
|
1983
|
+
// "liqPrice": "0",
|
|
1984
|
+
// "markPrice": "3032.37",
|
|
1985
|
+
// "unPnl": "-0.00008",
|
|
1986
|
+
// "positionMargin": "0",
|
|
1987
|
+
// "settleCoin": "USDC",
|
|
1988
|
+
// "im": "3.03245",
|
|
1989
|
+
// "mm": "0.007581125"
|
|
1990
|
+
// }
|
|
1991
|
+
// ],
|
|
1992
|
+
// "success": true
|
|
1993
|
+
// }
|
|
1994
|
+
//
|
|
1995
|
+
const data = this.safeList(response, 'data', []);
|
|
1996
|
+
return this.parsePositions(data, symbols);
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* @method
|
|
2000
|
+
* @name bydfi#fetchPositionsForSymbol
|
|
2001
|
+
* @description fetch open positions for a single market
|
|
2002
|
+
* @see https://developers.bydfi.com/en/swap/trade#positions-query
|
|
2003
|
+
* @description fetch all open positions for specific symbol
|
|
2004
|
+
* @param {string} symbol unified market symbol
|
|
2005
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2006
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2007
|
+
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
|
|
2008
|
+
*/
|
|
2009
|
+
async fetchPositionsForSymbol(symbol, params = {}) {
|
|
2010
|
+
await this.loadMarkets();
|
|
2011
|
+
const market = this.market(symbol);
|
|
2012
|
+
let contractType = 'FUTURE';
|
|
2013
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchPositions', 'contractType', contractType);
|
|
2014
|
+
const request = {
|
|
2015
|
+
'contractType': contractType,
|
|
2016
|
+
'symbol': market['id'],
|
|
2017
|
+
};
|
|
2018
|
+
const response = await this.privateGetV1SwapTradePositions(this.extend(request, params));
|
|
2019
|
+
const data = this.safeList(response, 'data', []);
|
|
2020
|
+
return this.parsePositions(data, [market['symbol']]);
|
|
2021
|
+
}
|
|
2022
|
+
parsePosition(position, market = undefined) {
|
|
2023
|
+
//
|
|
2024
|
+
// fetchPositions, fetchPositionsForSymbol
|
|
2025
|
+
// {
|
|
2026
|
+
// "symbol": "ETH-USDC",
|
|
2027
|
+
// "side": "BUY",
|
|
2028
|
+
// "volume": "0.001",
|
|
2029
|
+
// "avgPrice": "3032.45",
|
|
2030
|
+
// "liqPrice": "0",
|
|
2031
|
+
// "markPrice": "3032.37",
|
|
2032
|
+
// "unPnl": "-0.00008",
|
|
2033
|
+
// "positionMargin": "0",
|
|
2034
|
+
// "settleCoin": "USDC",
|
|
2035
|
+
// "im": "3.03245",
|
|
2036
|
+
// "mm": "0.007581125"
|
|
2037
|
+
// }
|
|
2038
|
+
//
|
|
2039
|
+
// fetchPositionsHistory
|
|
2040
|
+
// {
|
|
2041
|
+
// "id": "16788366",
|
|
2042
|
+
// "wallet": "W001",
|
|
2043
|
+
// "currency": "USDC",
|
|
2044
|
+
// "symbol": "ETH-USDC",
|
|
2045
|
+
// "side": "BUY",
|
|
2046
|
+
// "positionSide": "BOTH",
|
|
2047
|
+
// "leverage": 1,
|
|
2048
|
+
// "avgOpenPositionPrice": "3032.45",
|
|
2049
|
+
// "openPositionVolume": "1",
|
|
2050
|
+
// "openCount": 1,
|
|
2051
|
+
// "highPrice": "3032.45",
|
|
2052
|
+
// "lowPrice": "2953.67",
|
|
2053
|
+
// "avgClosePositionPrice": "2953.67",
|
|
2054
|
+
// "closePositionVolume": "1",
|
|
2055
|
+
// "closePositionCost": "2.95367",
|
|
2056
|
+
// "closeCount": 1,
|
|
2057
|
+
// "positionProfits": "-0.07878",
|
|
2058
|
+
// "lossBonus": "0",
|
|
2059
|
+
// "capitalFeeTotal": "-0.00026361",
|
|
2060
|
+
// "capitalFeeOutCash": "-0.00026361",
|
|
2061
|
+
// "capitalFeeInCash": "0",
|
|
2062
|
+
// "capitalFeeBonus": "0",
|
|
2063
|
+
// "openFeeTotal": "-0.00181947",
|
|
2064
|
+
// "openFeeBonus": "0",
|
|
2065
|
+
// "closeFeeTotal": "-0.00177221",
|
|
2066
|
+
// "closeFeeBonus": "0",
|
|
2067
|
+
// "liqLoss": "0",
|
|
2068
|
+
// "liqClosed": false,
|
|
2069
|
+
// "sequence": "53685341336",
|
|
2070
|
+
// "updateTime": "1766494929423",
|
|
2071
|
+
// "createTime": "1766423985842"
|
|
2072
|
+
// }
|
|
2073
|
+
//
|
|
2074
|
+
const marketId = this.safeString(position, 'symbol');
|
|
2075
|
+
market = this.safeMarket(marketId, market);
|
|
2076
|
+
const buyOrSell = this.safeString(position, 'side');
|
|
2077
|
+
const rawPositionSide = this.safeStringLower(position, 'positionSide');
|
|
2078
|
+
let positionSide = this.parsePositionSide(buyOrSell);
|
|
2079
|
+
let hedged = undefined;
|
|
2080
|
+
let isFetchPositionsHistory = false;
|
|
2081
|
+
if (rawPositionSide !== undefined) {
|
|
2082
|
+
isFetchPositionsHistory = true;
|
|
2083
|
+
if (rawPositionSide !== 'both') {
|
|
2084
|
+
positionSide = rawPositionSide;
|
|
2085
|
+
hedged = true;
|
|
2086
|
+
}
|
|
2087
|
+
else {
|
|
2088
|
+
hedged = false;
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
const contractSize = this.safeString(market, 'contractSize');
|
|
2092
|
+
let contracts = this.safeString2(position, 'volume', 'openPositionVolume');
|
|
2093
|
+
if (!isFetchPositionsHistory) {
|
|
2094
|
+
// in fetchPositions, the 'volume' is in base currency units, need to convert to contracts
|
|
2095
|
+
contracts = Precise.stringDiv(contracts, contractSize);
|
|
2096
|
+
}
|
|
2097
|
+
const timestamp = this.safeInteger(position, 'createTime');
|
|
2098
|
+
return this.safePosition({
|
|
2099
|
+
'info': position,
|
|
2100
|
+
'id': this.safeString(position, 'id'),
|
|
2101
|
+
'symbol': market['symbol'],
|
|
2102
|
+
'entryPrice': this.parseNumber(this.safeString2(position, 'avgOpenPositionPrice', 'avgPrice')),
|
|
2103
|
+
'markPrice': this.parseNumber(this.safeString(position, 'markPrice')),
|
|
2104
|
+
'lastPrice': this.parseNumber(this.safeString(position, 'avgClosePositionPrice')),
|
|
2105
|
+
'notional': this.parseNumber(this.safeString(position, 'closePositionCost')),
|
|
2106
|
+
'collateral': undefined,
|
|
2107
|
+
'unrealizedPnl': this.parseNumber(this.safeString(position, 'unPnl')),
|
|
2108
|
+
'realizedPnl': this.parseNumber(this.safeString(position, 'positionProfits')),
|
|
2109
|
+
'side': positionSide,
|
|
2110
|
+
'contracts': this.parseNumber(contracts),
|
|
2111
|
+
'contractSize': this.parseNumber(contractSize),
|
|
2112
|
+
'timestamp': timestamp,
|
|
2113
|
+
'datetime': this.iso8601(timestamp),
|
|
2114
|
+
'lastUpdateTimestamp': this.safeInteger(position, 'updateTime'),
|
|
2115
|
+
'hedged': hedged,
|
|
2116
|
+
'maintenanceMargin': this.parseNumber(this.safeString(position, 'mm')),
|
|
2117
|
+
'maintenanceMarginPercentage': undefined,
|
|
2118
|
+
'initialMargin': this.parseNumber(this.safeString(position, 'im')),
|
|
2119
|
+
'initialMarginPercentage': undefined,
|
|
2120
|
+
'leverage': this.parseNumber(this.safeString(position, 'leverage')),
|
|
2121
|
+
'liquidationPrice': this.parseNumber(this.safeString(position, 'liqPrice')),
|
|
2122
|
+
'marginRatio': undefined,
|
|
2123
|
+
'marginMode': undefined,
|
|
2124
|
+
'percentage': undefined,
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
parsePositionSide(side) {
|
|
2128
|
+
const sides = {
|
|
2129
|
+
'BUY': 'long',
|
|
2130
|
+
'SELL': 'short',
|
|
2131
|
+
};
|
|
2132
|
+
return this.safeString(sides, side, side);
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
2135
|
+
* @method
|
|
2136
|
+
* @name bydfi#fetchPositionHistory
|
|
2137
|
+
* @description fetches historical positions
|
|
2138
|
+
* @see https://developers.bydfi.com/en/swap/trade#query-historical-position-profit-and-loss-records
|
|
2139
|
+
* @param {string} symbol a unified market symbol
|
|
2140
|
+
* @param {int} [since] timestamp in ms of the earliest position to fetch , params["until"] - since <= 7 days
|
|
2141
|
+
* @param {int} [limit] the maximum amount of records to fetch (default 500, max 500)
|
|
2142
|
+
* @param {object} params extra parameters specific to the exchange api endpoint
|
|
2143
|
+
* @param {int} [params.until] timestamp in ms of the latest position to fetch , params["until"] - since <= 7 days
|
|
2144
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2145
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2146
|
+
* @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/?id=position-structure}
|
|
2147
|
+
*/
|
|
2148
|
+
async fetchPositionHistory(symbol, since = undefined, limit = undefined, params = {}) {
|
|
2149
|
+
await this.loadMarkets();
|
|
2150
|
+
const market = this.market(symbol);
|
|
2151
|
+
let contractType = 'FUTURE';
|
|
2152
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchPositionsHistory', 'contractType', contractType);
|
|
2153
|
+
const request = {
|
|
2154
|
+
'symbol': market['id'],
|
|
2155
|
+
'contractType': contractType,
|
|
2156
|
+
};
|
|
2157
|
+
params = this.handleSinceAndUntil('fetchPositionsHistory', since, params);
|
|
2158
|
+
if (limit !== undefined) {
|
|
2159
|
+
request['limit'] = limit;
|
|
2160
|
+
}
|
|
2161
|
+
const response = await this.privateGetV1SwapTradePositionHistory(this.extend(request, params));
|
|
2162
|
+
//
|
|
2163
|
+
//
|
|
2164
|
+
const data = this.safeList(response, 'data', []);
|
|
2165
|
+
const positions = this.parsePositions(data);
|
|
2166
|
+
return this.filterBySinceLimit(positions, since, limit);
|
|
2167
|
+
}
|
|
2168
|
+
/**
|
|
2169
|
+
* @method
|
|
2170
|
+
* @name bydfi#fetchPositionsHistory
|
|
2171
|
+
* @description fetches historical positions
|
|
2172
|
+
* @see https://developers.bydfi.com/en/swap/trade#query-historical-position-profit-and-loss-records
|
|
2173
|
+
* @param {string[]} symbols a list of unified market symbols
|
|
2174
|
+
* @param {int} [since] timestamp in ms of the earliest position to fetch , params["until"] - since <= 7 days
|
|
2175
|
+
* @param {int} [limit] the maximum amount of records to fetch (default 500, max 500)
|
|
2176
|
+
* @param {object} params extra parameters specific to the exchange api endpoint
|
|
2177
|
+
* @param {int} [params.until] timestamp in ms of the latest position to fetch , params["until"] - since <= 7 days
|
|
2178
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2179
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2180
|
+
* @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/?id=position-structure}
|
|
2181
|
+
*/
|
|
2182
|
+
async fetchPositionsHistory(symbols = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2183
|
+
await this.loadMarkets();
|
|
2184
|
+
let contractType = 'FUTURE';
|
|
2185
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchPositionsHistory', 'contractType', contractType);
|
|
2186
|
+
const request = {
|
|
2187
|
+
'contractType': contractType,
|
|
2188
|
+
};
|
|
2189
|
+
params = this.handleSinceAndUntil('fetchPositionsHistory', since, params);
|
|
2190
|
+
if (limit !== undefined) {
|
|
2191
|
+
request['limit'] = limit;
|
|
2192
|
+
}
|
|
2193
|
+
const response = await this.privateGetV1SwapTradePositionHistory(this.extend(request, params));
|
|
2194
|
+
//
|
|
2195
|
+
// {
|
|
2196
|
+
// "code": 200,
|
|
2197
|
+
// "message": "success",
|
|
2198
|
+
// "data": [
|
|
2199
|
+
// {
|
|
2200
|
+
// "id": "16788366",
|
|
2201
|
+
// "wallet": "W001",
|
|
2202
|
+
// "currency": "USDC",
|
|
2203
|
+
// "symbol": "ETH-USDC",
|
|
2204
|
+
// "side": "BUY",
|
|
2205
|
+
// "positionSide": "BOTH",
|
|
2206
|
+
// "leverage": 1,
|
|
2207
|
+
// "avgOpenPositionPrice": "3032.45",
|
|
2208
|
+
// "openPositionVolume": "1",
|
|
2209
|
+
// "openCount": 1,
|
|
2210
|
+
// "highPrice": "3032.45",
|
|
2211
|
+
// "lowPrice": "2953.67",
|
|
2212
|
+
// "avgClosePositionPrice": "2953.67",
|
|
2213
|
+
// "closePositionVolume": "1",
|
|
2214
|
+
// "closePositionCost": "2.95367",
|
|
2215
|
+
// "closeCount": 1,
|
|
2216
|
+
// "positionProfits": "-0.07878",
|
|
2217
|
+
// "lossBonus": "0",
|
|
2218
|
+
// "capitalFeeTotal": "-0.00026361",
|
|
2219
|
+
// "capitalFeeOutCash": "-0.00026361",
|
|
2220
|
+
// "capitalFeeInCash": "0",
|
|
2221
|
+
// "capitalFeeBonus": "0",
|
|
2222
|
+
// "openFeeTotal": "-0.00181947",
|
|
2223
|
+
// "openFeeBonus": "0",
|
|
2224
|
+
// "closeFeeTotal": "-0.00177221",
|
|
2225
|
+
// "closeFeeBonus": "0",
|
|
2226
|
+
// "liqLoss": "0",
|
|
2227
|
+
// "liqClosed": false,
|
|
2228
|
+
// "sequence": "53685341336",
|
|
2229
|
+
// "updateTime": "1766494929423",
|
|
2230
|
+
// "createTime": "1766423985842"
|
|
2231
|
+
// }
|
|
2232
|
+
// ],
|
|
2233
|
+
// "success": true
|
|
2234
|
+
// }
|
|
2235
|
+
//
|
|
2236
|
+
const data = this.safeList(response, 'data', []);
|
|
2237
|
+
const positions = this.parsePositions(data, symbols);
|
|
2238
|
+
return this.filterBySinceLimit(positions, since, limit);
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* @method
|
|
2242
|
+
* @name bydfi#fetchMarginMode
|
|
2243
|
+
* @description fetches the margin mode of a trading pair
|
|
2244
|
+
* @see https://developers.bydfi.com/en/swap/user#margin-mode-query
|
|
2245
|
+
* @param {string} symbol unified symbol of the market to fetch the margin mode for
|
|
2246
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2247
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2248
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2249
|
+
* @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/?id=margin-mode-structure}
|
|
2250
|
+
*/
|
|
2251
|
+
async fetchMarginMode(symbol, params = {}) {
|
|
2252
|
+
await this.loadMarkets();
|
|
2253
|
+
const market = this.market(symbol);
|
|
2254
|
+
let contractType = 'FUTURE';
|
|
2255
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchMarginMode', 'contractType', contractType);
|
|
2256
|
+
let wallet = 'W001';
|
|
2257
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchMarginMode', 'wallet', wallet);
|
|
2258
|
+
const request = {
|
|
2259
|
+
'contractType': contractType,
|
|
2260
|
+
'symbol': market['id'],
|
|
2261
|
+
'wallet': wallet,
|
|
2262
|
+
};
|
|
2263
|
+
const response = await this.privateGetV1SwapUserDataAssetsMargin(this.extend(request, params));
|
|
2264
|
+
//
|
|
2265
|
+
// {
|
|
2266
|
+
// "code": 200,
|
|
2267
|
+
// "message": "success",
|
|
2268
|
+
// "data": {
|
|
2269
|
+
// "wallet": "W001",
|
|
2270
|
+
// "symbol": "ETH-USDC",
|
|
2271
|
+
// "marginType": "CROSS"
|
|
2272
|
+
// },
|
|
2273
|
+
// "success": true
|
|
2274
|
+
// }
|
|
2275
|
+
//
|
|
2276
|
+
const data = this.safeDict(response, 'data', {});
|
|
2277
|
+
return this.parseMarginMode(data, market);
|
|
2278
|
+
}
|
|
2279
|
+
parseMarginMode(marginMode, market = undefined) {
|
|
2280
|
+
const marketId = this.safeString(marginMode, 'symbol');
|
|
2281
|
+
return {
|
|
2282
|
+
'info': marginMode,
|
|
2283
|
+
'symbol': this.safeSymbol(marketId, market),
|
|
2284
|
+
'marginMode': this.safeStringLower(marginMode, 'marginType'),
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* @method
|
|
2289
|
+
* @name bydfi#setMarginMode
|
|
2290
|
+
* @description set margin mode to 'cross' or 'isolated'
|
|
2291
|
+
* @see https://developers.bydfi.com/en/swap/user#change-margin-type-cross-margin
|
|
2292
|
+
* @param {string} marginMode 'cross' or 'isolated'
|
|
2293
|
+
* @param {string} symbol unified market symbol
|
|
2294
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2295
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2296
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2297
|
+
* @returns {object} response from the exchange
|
|
2298
|
+
*/
|
|
2299
|
+
async setMarginMode(marginMode, symbol = undefined, params = {}) {
|
|
2300
|
+
if (symbol === undefined) {
|
|
2301
|
+
throw new ArgumentsRequired(this.id + ' setMarginMode() requires a symbol argument');
|
|
2302
|
+
}
|
|
2303
|
+
marginMode = marginMode.toLowerCase();
|
|
2304
|
+
if (marginMode !== 'isolated' && marginMode !== 'cross') {
|
|
2305
|
+
throw new BadRequest(this.id + ' setMarginMode() marginMode argument should be isolated or cross');
|
|
2306
|
+
}
|
|
2307
|
+
await this.loadMarkets();
|
|
2308
|
+
const market = this.market(symbol);
|
|
2309
|
+
let contractType = 'FUTURE';
|
|
2310
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchMarginMode', 'contractType', contractType);
|
|
2311
|
+
let wallet = 'W001';
|
|
2312
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchMarginMode', 'wallet', wallet);
|
|
2313
|
+
const request = {
|
|
2314
|
+
'contractType': contractType,
|
|
2315
|
+
'symbol': market['id'],
|
|
2316
|
+
'marginType': marginMode.toUpperCase(),
|
|
2317
|
+
'wallet': wallet,
|
|
2318
|
+
};
|
|
2319
|
+
return await this.privatePostV1SwapUserDataMarginType(this.extend(request, params));
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* @method
|
|
2323
|
+
* @name bydfi#setPositionMode
|
|
2324
|
+
* @description set hedged to true or false for a market, hedged for bydfi is set identically for all markets with same settle currency
|
|
2325
|
+
* @see https://developers.bydfi.com/en/swap/user#change-position-mode-dual
|
|
2326
|
+
* @param {bool} hedged set to true to use dualSidePosition
|
|
2327
|
+
* @param {string} [symbol] not used by bydfi setPositionMode ()
|
|
2328
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2329
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2330
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2331
|
+
* @param {string} [params.settleCoin] The settlement currency - USDT or USDC or USD (default is USDT)
|
|
2332
|
+
* @returns {object} response from the exchange
|
|
2333
|
+
*/
|
|
2334
|
+
async setPositionMode(hedged, symbol = undefined, params = {}) {
|
|
2335
|
+
if (symbol !== undefined) {
|
|
2336
|
+
throw new NotSupported(this.id + ' setPositionMode() does not support a symbol argument. The position mode is set identically for all markets with same settle currency');
|
|
2337
|
+
}
|
|
2338
|
+
await this.loadMarkets();
|
|
2339
|
+
const positionType = hedged ? 'HEDGE' : 'ONEWAY';
|
|
2340
|
+
let wallet = 'W001';
|
|
2341
|
+
[wallet, params] = this.handleOptionAndParams(params, 'setPositionMode', 'wallet', wallet);
|
|
2342
|
+
let contractType = 'FUTURE';
|
|
2343
|
+
[contractType, params] = this.handleOptionAndParams(params, 'setPositionMode', 'contractType', contractType);
|
|
2344
|
+
let settleCoin = 'USDT';
|
|
2345
|
+
[settleCoin, params] = this.handleOptionAndParams(params, 'setPositionMode', 'settleCoin', settleCoin);
|
|
2346
|
+
const request = {
|
|
2347
|
+
'contractType': contractType,
|
|
2348
|
+
'wallet': wallet,
|
|
2349
|
+
'positionType': positionType,
|
|
2350
|
+
'settleCoin': settleCoin,
|
|
2351
|
+
};
|
|
2352
|
+
//
|
|
2353
|
+
// {
|
|
2354
|
+
// "code": 200,
|
|
2355
|
+
// "message": "success",
|
|
2356
|
+
// "success": true
|
|
2357
|
+
// }
|
|
2358
|
+
//
|
|
2359
|
+
return await this.privatePostV1SwapUserDataPositionSideDual(this.extend(request, params));
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* @method
|
|
2363
|
+
* @name bydfi#fetchPositionMode
|
|
2364
|
+
* @description fetchs the position mode, hedged or one way, hedged for bydfi is set identically for all markets with same settle currency
|
|
2365
|
+
* @see https://developers.bydfi.com/en/swap/user#get-position-mode
|
|
2366
|
+
* @param {string} [symbol] unified symbol of the market to fetch the order book for
|
|
2367
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2368
|
+
* @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE
|
|
2369
|
+
* @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2370
|
+
* @param {string} [params.settleCoin] The settlement currency - USDT or USDC or USD (default is USDT or settle currency of the market if market is provided)
|
|
2371
|
+
* @returns {object} an object detailing whether the market is in hedged or one-way mode
|
|
2372
|
+
*/
|
|
2373
|
+
async fetchPositionMode(symbol = undefined, params = {}) {
|
|
2374
|
+
await this.loadMarkets();
|
|
2375
|
+
let wallet = 'W001';
|
|
2376
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchPositionMode', 'wallet', wallet);
|
|
2377
|
+
let contractType = 'FUTURE';
|
|
2378
|
+
[contractType, params] = this.handleOptionAndParams(params, 'fetchPositionMode', 'contractType', contractType);
|
|
2379
|
+
let settleCoin = 'USDT';
|
|
2380
|
+
if (symbol === undefined) {
|
|
2381
|
+
[settleCoin, params] = this.handleOptionAndParams(params, 'fetchPositionMode', 'settleCoin', settleCoin);
|
|
2382
|
+
}
|
|
2383
|
+
else {
|
|
2384
|
+
const market = this.market(symbol);
|
|
2385
|
+
settleCoin = market['settleId'];
|
|
2386
|
+
}
|
|
2387
|
+
const request = {
|
|
2388
|
+
'contractType': contractType,
|
|
2389
|
+
'settleCoin': settleCoin,
|
|
2390
|
+
'wallet': wallet,
|
|
2391
|
+
};
|
|
2392
|
+
const response = await this.privateGetV1SwapUserDataPositionSideDual(this.extend(request, params));
|
|
2393
|
+
//
|
|
2394
|
+
// {
|
|
2395
|
+
// "code": 200,
|
|
2396
|
+
// "message": "success",
|
|
2397
|
+
// "data": {
|
|
2398
|
+
// "wallet": "W001",
|
|
2399
|
+
// "contractType": "FUTURE",
|
|
2400
|
+
// "settleCoin": "USDT",
|
|
2401
|
+
// "positionType": "HEDGE",
|
|
2402
|
+
// "unitModel": 2,
|
|
2403
|
+
// "pricingModel": "FLAG",
|
|
2404
|
+
// "priceProtection": "CLOSE",
|
|
2405
|
+
// "totalWallet": 2
|
|
2406
|
+
// },
|
|
2407
|
+
// "success": true
|
|
2408
|
+
// }
|
|
2409
|
+
//
|
|
2410
|
+
const data = this.safeDict(response, 'data', {});
|
|
2411
|
+
const hedged = this.safeString(data, 'positionType') === 'HEDGE';
|
|
2412
|
+
return {
|
|
2413
|
+
'info': response,
|
|
2414
|
+
'hedged': hedged,
|
|
2415
|
+
};
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* @method
|
|
2419
|
+
* @name bydfi#fetchBalance
|
|
2420
|
+
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
2421
|
+
* @see https://developers.bydfi.com/en/account#asset-inquiry
|
|
2422
|
+
* @see https://developers.bydfi.com/en/swap/user#asset-query
|
|
2423
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2424
|
+
* @param {string} [params.accountType] the type of account to fetch the balance for, either 'spot' or 'swap' or 'funding' (default is 'spot')
|
|
2425
|
+
* @param {string} [params.wallet] *swap only* The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract
|
|
2426
|
+
* @param {string} [params.asset] currency id for the balance to fetch
|
|
2427
|
+
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
|
|
2428
|
+
*/
|
|
2429
|
+
async fetchBalance(params = {}) {
|
|
2430
|
+
await this.loadMarkets();
|
|
2431
|
+
let accountType = 'spot';
|
|
2432
|
+
[accountType, params] = this.handleOptionAndParams2(params, 'fetchBalance', 'accountType', 'type', accountType);
|
|
2433
|
+
const request = {};
|
|
2434
|
+
let response = undefined;
|
|
2435
|
+
if (accountType !== 'swap') {
|
|
2436
|
+
const options = this.safeDict(this.options, 'accountsByType', {});
|
|
2437
|
+
const parsedAccountType = this.safeString(options, accountType, accountType);
|
|
2438
|
+
request['walletType'] = parsedAccountType;
|
|
2439
|
+
//
|
|
2440
|
+
// {
|
|
2441
|
+
// "code": 200,
|
|
2442
|
+
// "message": "success",
|
|
2443
|
+
// "data": [
|
|
2444
|
+
// {
|
|
2445
|
+
// "walletType": "spot",
|
|
2446
|
+
// "asset": "USDC",
|
|
2447
|
+
// "total": "100",
|
|
2448
|
+
// "available": "100",
|
|
2449
|
+
// "frozen": "0"
|
|
2450
|
+
// }
|
|
2451
|
+
// ],
|
|
2452
|
+
// "success": true
|
|
2453
|
+
// }
|
|
2454
|
+
//
|
|
2455
|
+
response = await this.privateGetV1AccountAssets(this.extend(request, params));
|
|
2456
|
+
}
|
|
2457
|
+
else {
|
|
2458
|
+
let wallet = 'W001';
|
|
2459
|
+
[wallet, params] = this.handleOptionAndParams(params, 'fetchBalance', 'wallet', wallet);
|
|
2460
|
+
request['wallet'] = wallet;
|
|
2461
|
+
//
|
|
2462
|
+
// {
|
|
2463
|
+
// "code": 200,
|
|
2464
|
+
// "message": "success",
|
|
2465
|
+
// "data": [
|
|
2466
|
+
// {
|
|
2467
|
+
// "wallet": "W001",
|
|
2468
|
+
// "asset": "USDT",
|
|
2469
|
+
// "balance": "0",
|
|
2470
|
+
// "frozen": "0",
|
|
2471
|
+
// "positionMargin": "0",
|
|
2472
|
+
// "availableBalance": "0",
|
|
2473
|
+
// "canWithdrawAmount": "0",
|
|
2474
|
+
// "bonusAmount": "0"
|
|
2475
|
+
// },
|
|
2476
|
+
// {
|
|
2477
|
+
// "wallet": "W001",
|
|
2478
|
+
// "asset": "USDC",
|
|
2479
|
+
// "balance": "99.99505828",
|
|
2480
|
+
// "frozen": "4.0024",
|
|
2481
|
+
// "positionMargin": "2.95342",
|
|
2482
|
+
// "availableBalance": "92.96020828",
|
|
2483
|
+
// "canWithdrawAmount": "92.96020828",
|
|
2484
|
+
// "bonusAmount": "0"
|
|
2485
|
+
// }
|
|
2486
|
+
// ],
|
|
2487
|
+
// "success": true
|
|
2488
|
+
// }
|
|
2489
|
+
response = await this.privateGetV1SwapAccountBalance(this.extend(request, params));
|
|
2490
|
+
}
|
|
2491
|
+
const data = this.safeList(response, 'data', []);
|
|
2492
|
+
return this.parseBalance(data);
|
|
2493
|
+
}
|
|
2494
|
+
parseBalance(response) {
|
|
2495
|
+
const timestamp = this.milliseconds();
|
|
2496
|
+
const result = {
|
|
2497
|
+
'info': response,
|
|
2498
|
+
'timestamp': timestamp,
|
|
2499
|
+
'datetime': this.iso8601(timestamp),
|
|
2500
|
+
};
|
|
2501
|
+
for (let i = 0; i < response.length; i++) {
|
|
2502
|
+
const balance = response[i];
|
|
2503
|
+
const symbol = this.safeString(balance, 'asset');
|
|
2504
|
+
const code = this.safeCurrencyCode(symbol);
|
|
2505
|
+
const account = this.account();
|
|
2506
|
+
account['total'] = this.safeString2(balance, 'total', 'balance');
|
|
2507
|
+
account['free'] = this.safeString2(balance, 'available', 'availableBalance');
|
|
2508
|
+
result[code] = account;
|
|
2509
|
+
}
|
|
2510
|
+
return this.safeBalance(result);
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* @method
|
|
2514
|
+
* @name budfi#transfer
|
|
2515
|
+
* @description transfer currency internally between wallets on the same account
|
|
2516
|
+
* @see https://developers.bydfi.com/en/account#asset-transfer-between-accounts
|
|
2517
|
+
* @param {string} code unified currency code
|
|
2518
|
+
* @param {float} amount amount to transfer
|
|
2519
|
+
* @param {string} fromAccount 'spot', 'funding', or 'swap'
|
|
2520
|
+
* @param {string} toAccount 'spot', 'funding', or 'swap'
|
|
2521
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2522
|
+
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/?id=transfer-structure}
|
|
2523
|
+
*/
|
|
2524
|
+
async transfer(code, amount, fromAccount, toAccount, params = {}) {
|
|
2525
|
+
await this.loadMarkets();
|
|
2526
|
+
const currency = this.currency(code);
|
|
2527
|
+
const accountsByType = this.safeDict(this.options, 'accountsByType', {});
|
|
2528
|
+
const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
|
|
2529
|
+
const toId = this.safeString(accountsByType, toAccount, toAccount);
|
|
2530
|
+
const request = {
|
|
2531
|
+
'asset': currency['id'],
|
|
2532
|
+
'amount': this.currencyToPrecision(code, amount),
|
|
2533
|
+
'fromType': fromId,
|
|
2534
|
+
'toType': toId,
|
|
2535
|
+
};
|
|
2536
|
+
const response = await this.privatePostV1AccountTransfer(this.extend(request, params));
|
|
2537
|
+
//
|
|
2538
|
+
// {
|
|
2539
|
+
// "code": 200,
|
|
2540
|
+
// "message": "success",
|
|
2541
|
+
// "success": true
|
|
2542
|
+
// }
|
|
2543
|
+
//
|
|
2544
|
+
const transfer = this.parseTransfer(response, currency);
|
|
2545
|
+
const transferOptions = this.safeDict(this.options, 'transfer', {});
|
|
2546
|
+
const fillResponseFromRequest = this.safeBool(transferOptions, 'fillResponseFromRequest', true);
|
|
2547
|
+
if (fillResponseFromRequest) {
|
|
2548
|
+
const timestamp = this.milliseconds();
|
|
2549
|
+
transfer['timestamp'] = timestamp;
|
|
2550
|
+
transfer['datetime'] = this.iso8601(timestamp);
|
|
2551
|
+
transfer['currency'] = code;
|
|
2552
|
+
transfer['fromAccount'] = fromAccount;
|
|
2553
|
+
transfer['toAccount'] = toAccount;
|
|
2554
|
+
transfer['amount'] = amount;
|
|
2555
|
+
}
|
|
2556
|
+
return transfer;
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* @method
|
|
2560
|
+
* @name bydfi#fetchTransfers
|
|
2561
|
+
* @description fetch a history of internal transfers made on an account
|
|
2562
|
+
* @see https://developers.bydfi.com/en/account#query-wallet-transfer-records
|
|
2563
|
+
* @param {string} code unified currency code of the currency transferred
|
|
2564
|
+
* @param {int} [since] the earliest time in ms to fetch transfers for
|
|
2565
|
+
* @param {int} [limit] the maximum number of transfers structures to retrieve (default 10)
|
|
2566
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2567
|
+
* @param {int} [params.until] the latest time in ms to fetch entries for
|
|
2568
|
+
* @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/?id=transfer-structure}
|
|
2569
|
+
*/
|
|
2570
|
+
async fetchTransfers(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2571
|
+
if (code === undefined) {
|
|
2572
|
+
throw new ArgumentsRequired(this.id + ' fetchTransfers() requires a code argument');
|
|
2573
|
+
}
|
|
2574
|
+
await this.loadMarkets();
|
|
2575
|
+
const currency = this.currency(code);
|
|
2576
|
+
const paginate = this.safeBool(params, 'paginate', false);
|
|
2577
|
+
if (paginate) {
|
|
2578
|
+
const maxLimit = 50;
|
|
2579
|
+
params = this.omit(params, 'paginate');
|
|
2580
|
+
params = this.extend(params, { 'paginationDirection': 'backward' });
|
|
2581
|
+
const paginatedResponse = await this.fetchPaginatedCallDynamic('fetchTransfers', currency['code'], since, limit, params, maxLimit, true);
|
|
2582
|
+
return this.sortBy(paginatedResponse, 'timestamp');
|
|
2583
|
+
}
|
|
2584
|
+
const request = {
|
|
2585
|
+
'asset': currency['id'],
|
|
2586
|
+
};
|
|
2587
|
+
let until = undefined;
|
|
2588
|
+
[until, params] = this.handleOptionAndParams2(params, 'fetchTransfers', 'until', 'endTime');
|
|
2589
|
+
if (until === undefined) {
|
|
2590
|
+
until = this.milliseconds(); // exchange requires endTime
|
|
2591
|
+
}
|
|
2592
|
+
if (since === undefined) {
|
|
2593
|
+
since = 1; // exchange requires startTime but allows any value
|
|
2594
|
+
}
|
|
2595
|
+
request['startTime'] = since;
|
|
2596
|
+
request['endTime'] = until;
|
|
2597
|
+
if (limit !== undefined) {
|
|
2598
|
+
request['rows'] = limit;
|
|
2599
|
+
}
|
|
2600
|
+
const response = await this.privateGetV1AccountTransferRecords(this.extend(request, params));
|
|
2601
|
+
//
|
|
2602
|
+
// {
|
|
2603
|
+
// "code": 200,
|
|
2604
|
+
// "message": "success",
|
|
2605
|
+
// "data": [
|
|
2606
|
+
// {
|
|
2607
|
+
// "orderId": "1209991065294581760",
|
|
2608
|
+
// "txId": "6km5fRK83Gwdp43HA479DW1Colh2pKyS",
|
|
2609
|
+
// "sourceWallet": "SPOT",
|
|
2610
|
+
// "targetWallet": "SWAP",
|
|
2611
|
+
// "asset": "USDC",
|
|
2612
|
+
// "amount": "100",
|
|
2613
|
+
// "status": "SUCCESS",
|
|
2614
|
+
// "timestamp": 1766413950000
|
|
2615
|
+
// }
|
|
2616
|
+
// ],
|
|
2617
|
+
// "success": true
|
|
2618
|
+
// }
|
|
2619
|
+
//
|
|
2620
|
+
const data = this.safeList(response, 'data', []);
|
|
2621
|
+
return this.parseTransfers(data, currency, since, limit);
|
|
2622
|
+
}
|
|
2623
|
+
parseTransfer(transfer, currency = undefined) {
|
|
2624
|
+
//
|
|
2625
|
+
// transfer
|
|
2626
|
+
// {
|
|
2627
|
+
// "code": 200,
|
|
2628
|
+
// "message": "success",
|
|
2629
|
+
// "success": true
|
|
2630
|
+
// }
|
|
2631
|
+
//
|
|
2632
|
+
// fetchTransfers
|
|
2633
|
+
// {
|
|
2634
|
+
// "orderId": "1209991065294581760",
|
|
2635
|
+
// "txId": "6km5fRK83Gwdp43HA479DW1Colh2pKyS",
|
|
2636
|
+
// "sourceWallet": "SPOT",
|
|
2637
|
+
// "targetWallet": "SWAP",
|
|
2638
|
+
// "asset": "USDC",
|
|
2639
|
+
// "amount": "100",
|
|
2640
|
+
// "status": "SUCCESS",
|
|
2641
|
+
// "timestamp": 1766413950000
|
|
2642
|
+
// }
|
|
2643
|
+
//
|
|
2644
|
+
const status = this.safeStringUpper2(transfer, 'message', 'status');
|
|
2645
|
+
const accountsById = this.safeDict(this.options, 'accountsById', {});
|
|
2646
|
+
const fromId = this.safeStringUpper(transfer, 'sourceWallet');
|
|
2647
|
+
const toId = this.safeStringUpper(transfer, 'targetWallet');
|
|
2648
|
+
const fromAccount = this.safeString(accountsById, fromId, fromId);
|
|
2649
|
+
const toAccount = this.safeString(accountsById, toId, toId);
|
|
2650
|
+
const timestamp = this.safeInteger(transfer, 'timestamp');
|
|
2651
|
+
const currencyId = this.safeString(transfer, 'asset');
|
|
2652
|
+
return {
|
|
2653
|
+
'info': transfer,
|
|
2654
|
+
'id': this.safeString(transfer, 'txId'),
|
|
2655
|
+
'timestamp': timestamp,
|
|
2656
|
+
'datetime': this.iso8601(timestamp),
|
|
2657
|
+
'currency': this.safeCurrencyCode(currencyId, currency),
|
|
2658
|
+
'amount': this.safeNumber(transfer, 'amount'),
|
|
2659
|
+
'fromAccount': fromAccount,
|
|
2660
|
+
'toAccount': toAccount,
|
|
2661
|
+
'status': this.paraseTransferStatus(status),
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
paraseTransferStatus(status) {
|
|
2665
|
+
const statuses = {
|
|
2666
|
+
'SUCCESS': 'ok',
|
|
2667
|
+
'WAIT': 'pending',
|
|
2668
|
+
'FAILED': 'failed',
|
|
2669
|
+
};
|
|
2670
|
+
return this.safeString(statuses, status, status);
|
|
2671
|
+
}
|
|
2672
|
+
/**
|
|
2673
|
+
* @method
|
|
2674
|
+
* @name bydfi#fetchDeposits
|
|
2675
|
+
* @description fetch all deposits made to an account
|
|
2676
|
+
* @see https://developers.bydfi.com/en/spot/account#query-deposit-records
|
|
2677
|
+
* @param {string} code unified currency code (mandatory)
|
|
2678
|
+
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
2679
|
+
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
2680
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2681
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/?id=transaction-structure}
|
|
2682
|
+
*/
|
|
2683
|
+
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2684
|
+
return await this.fetchTransactionsHelper('deposit', code, since, limit, params);
|
|
2685
|
+
}
|
|
2686
|
+
/**
|
|
2687
|
+
* @method
|
|
2688
|
+
* @name bydfi#fetchWithdrawals
|
|
2689
|
+
* @description fetch all withdrawals made from an account
|
|
2690
|
+
* @see https://developers.bydfi.com/en/spot/account#query-withdrawal-records
|
|
2691
|
+
* @param {string} code unified currency code (mandatory)
|
|
2692
|
+
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
2693
|
+
* @param {int} [limit] the maximum number of withdrawal structures to retrieve
|
|
2694
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2695
|
+
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/?id=transaction-structure}
|
|
2696
|
+
*/
|
|
2697
|
+
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
2698
|
+
return await this.fetchTransactionsHelper('withdrawal', code, since, limit, params);
|
|
2699
|
+
}
|
|
2700
|
+
async fetchTransactionsHelper(type, code, since, limit, params) {
|
|
2701
|
+
const methodName = (type === 'deposit') ? 'fetchDeposits' : 'fetchWithdrawals';
|
|
2702
|
+
if (code === undefined) {
|
|
2703
|
+
throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a code argument');
|
|
2704
|
+
}
|
|
2705
|
+
await this.loadMarkets();
|
|
2706
|
+
const currency = this.currency(code);
|
|
2707
|
+
const paginate = this.safeBool(params, 'paginate', false);
|
|
2708
|
+
if (paginate) {
|
|
2709
|
+
const maxLimit = 50;
|
|
2710
|
+
params = this.omit(params, 'paginate');
|
|
2711
|
+
params = this.extend(params, { 'paginationDirection': 'backward' });
|
|
2712
|
+
const paginatedResponse = await this.fetchPaginatedCallDynamic(methodName, currency['code'], since, limit, params, maxLimit, true);
|
|
2713
|
+
return this.sortBy(paginatedResponse, 'timestamp');
|
|
2714
|
+
}
|
|
2715
|
+
const request = {
|
|
2716
|
+
'asset': currency['id'],
|
|
2717
|
+
};
|
|
2718
|
+
let until = undefined;
|
|
2719
|
+
[until, params] = this.handleOptionAndParams2(params, 'fetchTransfers', 'until', 'endTime');
|
|
2720
|
+
const now = this.milliseconds();
|
|
2721
|
+
const sevenDays = 7 * 24 * 60 * 60 * 1000; // the maximum range is 7 days
|
|
2722
|
+
let startTime = since;
|
|
2723
|
+
if (startTime === undefined) {
|
|
2724
|
+
if (until === undefined) {
|
|
2725
|
+
// both since and until are undefined
|
|
2726
|
+
startTime = now - sevenDays;
|
|
2727
|
+
until = now;
|
|
2728
|
+
}
|
|
2729
|
+
else {
|
|
2730
|
+
// since is undefined but until is defined
|
|
2731
|
+
startTime = until - sevenDays;
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
else if (until === undefined) {
|
|
2735
|
+
// until is undefined but since is defined
|
|
2736
|
+
const delta = now - startTime;
|
|
2737
|
+
if (delta > sevenDays) {
|
|
2738
|
+
until = startTime + sevenDays;
|
|
2739
|
+
}
|
|
2740
|
+
else {
|
|
2741
|
+
until = now;
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
request['startTime'] = startTime;
|
|
2745
|
+
request['endTime'] = until;
|
|
2746
|
+
if (limit !== undefined) {
|
|
2747
|
+
request['limit'] = limit;
|
|
2748
|
+
}
|
|
2749
|
+
let response = undefined;
|
|
2750
|
+
if (type === 'deposit') {
|
|
2751
|
+
//
|
|
2752
|
+
// {
|
|
2753
|
+
// "code": 200,
|
|
2754
|
+
// "message": "success",
|
|
2755
|
+
// "data": [
|
|
2756
|
+
// {
|
|
2757
|
+
// "orderId": "1208864446987255809",
|
|
2758
|
+
// "asset": "USDC",
|
|
2759
|
+
// "amount": "200",
|
|
2760
|
+
// "status": "SUCCESS",
|
|
2761
|
+
// "txId": "0xd059a82a55ffc737722bd23c1ef3db2884ce8525b72ff0b3c038b430ce0c8ca5",
|
|
2762
|
+
// "network": "ETH",
|
|
2763
|
+
// "address": "0x8346b46f6aa9843c09f79f1c170a37aca83c8fcd",
|
|
2764
|
+
// "addressTag": null,
|
|
2765
|
+
// "finishTime": 1766145475000,
|
|
2766
|
+
// "createTime": 1766145344000
|
|
2767
|
+
// }
|
|
2768
|
+
// ],
|
|
2769
|
+
// "success": true
|
|
2770
|
+
// }
|
|
2771
|
+
//
|
|
2772
|
+
response = await this.privateGetV1SpotDepositRecords(this.extend(request, params));
|
|
2773
|
+
}
|
|
2774
|
+
else {
|
|
2775
|
+
//
|
|
2776
|
+
// todo check after withdrawal
|
|
2777
|
+
//
|
|
2778
|
+
response = await this.privateGetV1SpotWithdrawRecords(this.extend(request, params));
|
|
2779
|
+
}
|
|
2780
|
+
const data = this.safeList(response, 'data', []);
|
|
2781
|
+
const transactionParams = {
|
|
2782
|
+
'type': type,
|
|
2783
|
+
};
|
|
2784
|
+
params = this.extend(params, transactionParams);
|
|
2785
|
+
return this.parseTransactions(data, currency, since, limit, params);
|
|
2786
|
+
}
|
|
2787
|
+
parseTransaction(transaction, currency = undefined) {
|
|
2788
|
+
//
|
|
2789
|
+
// fetchDeposits
|
|
2790
|
+
// {
|
|
2791
|
+
// "orderId": "1208864446987255809",
|
|
2792
|
+
// "asset": "USDC",
|
|
2793
|
+
// "amount": "200",
|
|
2794
|
+
// "status": "SUCCESS",
|
|
2795
|
+
// "txId": "0xd059a82a55ffc737722bd23c1ef3db2884ce8525b72ff0b3c038b430ce0c8ca5",
|
|
2796
|
+
// "network": "ETH",
|
|
2797
|
+
// "address": "0x8346b46f6aa9843c09f79f1c170a37aca83c8fcd",
|
|
2798
|
+
// "addressTag": null,
|
|
2799
|
+
// "finishTime": 1766145475000,
|
|
2800
|
+
// "createTime": 1766145344000
|
|
2801
|
+
// }
|
|
2802
|
+
//
|
|
2803
|
+
const currencyId = this.safeString(transaction, 'asset');
|
|
2804
|
+
const code = this.safeCurrencyCode(currencyId, currency);
|
|
2805
|
+
const rawStatus = this.safeStringLower(transaction, 'status');
|
|
2806
|
+
const timestamp = this.safeInteger(transaction, 'createTime');
|
|
2807
|
+
let fee = undefined;
|
|
2808
|
+
const feeCost = this.safeNumber(transaction, 'fee');
|
|
2809
|
+
if (feeCost !== undefined) {
|
|
2810
|
+
fee = {
|
|
2811
|
+
'cost': feeCost,
|
|
2812
|
+
'currency': undefined,
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2815
|
+
return {
|
|
2816
|
+
'info': transaction,
|
|
2817
|
+
'id': this.safeString(transaction, 'orderId'),
|
|
2818
|
+
'txid': this.safeString(transaction, 'txId'),
|
|
2819
|
+
'type': undefined,
|
|
2820
|
+
'currency': code,
|
|
2821
|
+
'network': this.networkIdToCode(this.safeString(transaction, 'network')),
|
|
2822
|
+
'amount': this.safeNumber(transaction, 'amount'),
|
|
2823
|
+
'status': this.parseTransactionStatus(rawStatus),
|
|
2824
|
+
'timestamp': timestamp,
|
|
2825
|
+
'datetime': this.iso8601(timestamp),
|
|
2826
|
+
'address': this.safeString(transaction, 'address'),
|
|
2827
|
+
'addressFrom': undefined,
|
|
2828
|
+
'addressTo': undefined,
|
|
2829
|
+
'tag': this.safeString(transaction, 'addressTag'),
|
|
2830
|
+
'tagFrom': undefined,
|
|
2831
|
+
'tagTo': undefined,
|
|
2832
|
+
'updated': this.safeInteger(transaction, 'finishTime'),
|
|
2833
|
+
'comment': undefined,
|
|
2834
|
+
'fee': fee,
|
|
2835
|
+
'internal': false,
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
parseTransactionStatus(status) {
|
|
2839
|
+
const statuses = {
|
|
2840
|
+
'success': 'ok',
|
|
2841
|
+
'wait': 'pending',
|
|
2842
|
+
'failed': 'failed',
|
|
2843
|
+
};
|
|
2844
|
+
return this.safeString(statuses, status, status);
|
|
2845
|
+
}
|
|
2846
|
+
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
2847
|
+
let url = this.urls['api'][api];
|
|
2848
|
+
let endpoint = '/' + path;
|
|
2849
|
+
let query = '';
|
|
2850
|
+
const sortedParams = this.keysort(params);
|
|
2851
|
+
if (method === 'GET') {
|
|
2852
|
+
query = this.urlencode(sortedParams);
|
|
2853
|
+
if (query.length !== 0) {
|
|
2854
|
+
endpoint += '?' + query;
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
if (api === 'private') {
|
|
2858
|
+
this.checkRequiredCredentials();
|
|
2859
|
+
const timestamp = this.milliseconds().toString();
|
|
2860
|
+
if (method === 'GET') {
|
|
2861
|
+
const payload = this.apiKey + timestamp + query;
|
|
2862
|
+
const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256, 'hex');
|
|
2863
|
+
headers = {
|
|
2864
|
+
'X-API-KEY': this.apiKey,
|
|
2865
|
+
'X-API-TIMESTAMP': timestamp,
|
|
2866
|
+
'X-API-SIGNATURE': signature,
|
|
2867
|
+
};
|
|
2868
|
+
}
|
|
2869
|
+
else {
|
|
2870
|
+
body = this.json(sortedParams);
|
|
2871
|
+
const payload = this.apiKey + timestamp + body;
|
|
2872
|
+
const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256, 'hex');
|
|
2873
|
+
headers = {
|
|
2874
|
+
'Content-Type': 'application/json',
|
|
2875
|
+
'X-API-KEY': this.apiKey,
|
|
2876
|
+
'X-API-TIMESTAMP': timestamp,
|
|
2877
|
+
'X-API-SIGNATURE': signature,
|
|
2878
|
+
};
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
url += endpoint;
|
|
2882
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
2883
|
+
}
|
|
2884
|
+
handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
2885
|
+
if (response === undefined) {
|
|
2886
|
+
return undefined; // fallback to default error handler
|
|
2887
|
+
}
|
|
2888
|
+
//
|
|
2889
|
+
// {
|
|
2890
|
+
// "code": 101107,
|
|
2891
|
+
// "message": "Requires transaction permissions"
|
|
2892
|
+
// }
|
|
2893
|
+
//
|
|
2894
|
+
const code = this.safeString(response, 'code');
|
|
2895
|
+
const message = this.safeString(response, 'message');
|
|
2896
|
+
if (code !== '200') {
|
|
2897
|
+
const feedback = this.id + ' ' + body;
|
|
2898
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
|
|
2899
|
+
this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
|
|
2900
|
+
this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
|
|
2901
|
+
throw new ExchangeError(feedback); // unknown message
|
|
2902
|
+
}
|
|
2903
|
+
return undefined;
|
|
2904
|
+
}
|
|
2905
|
+
}
|