ccxt 4.4.68 → 4.4.69

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.
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/paradex.js';
2
- import type { Str, Num, Dict, Int, Market, OrderType, OrderSide, Order, OrderBook, Strings, Ticker, Tickers, Trade, Balances, Currency, Transaction, OHLCV, Position, int } from './base/types.js';
2
+ import type { Str, Num, Dict, Int, Market, OrderType, OrderSide, Order, OrderBook, Strings, Ticker, Tickers, Trade, Balances, Currency, Transaction, OHLCV, Position, int, MarginMode, Leverage } from './base/types.js';
3
3
  /**
4
4
  * @class paradex
5
5
  * @description Paradex is a decentralized exchange built on the StarkWare layer 2 scaling solution. To access private methods you can either use the ETH public key and private key by setting (exchange.privateKey and exchange.walletAddress)
@@ -311,6 +311,53 @@ export default class paradex extends Exchange {
311
311
  fetchWithdrawals(code?: Str, since?: Int, limit?: Int, params?: {}): Promise<Transaction[]>;
312
312
  parseTransaction(transaction: Dict, currency?: Currency): Transaction;
313
313
  parseTransactionStatus(status: Str): string;
314
+ /**
315
+ * @method
316
+ * @name paradex#fetchMarginMode
317
+ * @description fetches the margin mode of a specific symbol
318
+ * @see https://docs.api.testnet.paradex.trade/#get-account-margin-configuration
319
+ * @param {string} symbol unified symbol of the market the order was made in
320
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
321
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
322
+ */
323
+ fetchMarginMode(symbol: string, params?: {}): Promise<MarginMode>;
324
+ parseMarginMode(rawMarginMode: Dict, market?: any): MarginMode;
325
+ /**
326
+ * @method
327
+ * @name paradex#setMarginMode
328
+ * @description set margin mode to 'cross' or 'isolated'
329
+ * @see https://docs.api.testnet.paradex.trade/#set-margin-configuration
330
+ * @param {string} marginMode 'cross' or 'isolated'
331
+ * @param {string} symbol unified market symbol
332
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
333
+ * @param {float} [params.leverage] the rate of leverage
334
+ * @returns {object} response from the exchange
335
+ */
336
+ setMarginMode(marginMode: string, symbol?: Str, params?: {}): Promise<any>;
337
+ /**
338
+ * @method
339
+ * @name paradex#fetchLeverage
340
+ * @description fetch the set leverage for a market
341
+ * @see https://docs.api.testnet.paradex.trade/#get-account-margin-configuration
342
+ * @param {string} symbol unified market symbol
343
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
344
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
345
+ */
346
+ fetchLeverage(symbol: string, params?: {}): Promise<Leverage>;
347
+ parseLeverage(leverage: Dict, market?: Market): Leverage;
348
+ encodeMarginMode(mode: any): string;
349
+ /**
350
+ * @method
351
+ * @name paradex#setLeverage
352
+ * @description set the level of leverage for a market
353
+ * @see https://docs.api.testnet.paradex.trade/#set-margin-configuration
354
+ * @param {float} leverage the rate of leverage
355
+ * @param {string} [symbol] unified market symbol (is mandatory for swap markets)
356
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
357
+ * @param {string} [params.marginMode] 'cross' or 'isolated'
358
+ * @returns {object} response from the exchange
359
+ */
360
+ setLeverage(leverage: Int, symbol?: Str, params?: {}): Promise<any>;
314
361
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
315
362
  url: string;
316
363
  method: string;
package/js/src/paradex.js CHANGED
@@ -73,10 +73,10 @@ export default class paradex extends Exchange {
73
73
  'fetchIsolatedBorrowRate': false,
74
74
  'fetchIsolatedBorrowRates': false,
75
75
  'fetchLedger': false,
76
- 'fetchLeverage': false,
76
+ 'fetchLeverage': true,
77
77
  'fetchLeverageTiers': false,
78
78
  'fetchLiquidations': true,
79
- 'fetchMarginMode': undefined,
79
+ 'fetchMarginMode': true,
80
80
  'fetchMarketLeverageTiers': false,
81
81
  'fetchMarkets': true,
82
82
  'fetchMarkOHLCV': false,
@@ -110,8 +110,8 @@ export default class paradex extends Exchange {
110
110
  'repayCrossMargin': false,
111
111
  'repayIsolatedMargin': false,
112
112
  'sandbox': true,
113
- 'setLeverage': false,
114
- 'setMarginMode': false,
113
+ 'setLeverage': true,
114
+ 'setMarginMode': true,
115
115
  'setPositionMode': false,
116
116
  'transfer': false,
117
117
  'withdraw': false,
@@ -153,12 +153,23 @@ export default class paradex extends Exchange {
153
153
  'system/state': 1,
154
154
  'system/time': 1,
155
155
  'trades': 1,
156
+ 'vaults': 1,
157
+ 'vaults/balance': 1,
158
+ 'vaults/config': 1,
159
+ 'vaults/history': 1,
160
+ 'vaults/positions': 1,
161
+ 'vaults/summary': 1,
162
+ 'vaults/transfers': 1,
156
163
  },
157
164
  },
158
165
  'private': {
159
166
  'get': {
160
167
  'account': 1,
168
+ 'account/info': 1,
169
+ 'account/history': 1,
170
+ 'account/margin': 1,
161
171
  'account/profile': 1,
172
+ 'account/subaccounts': 1,
162
173
  'balance': 1,
163
174
  'fills': 1,
164
175
  'funding/payments': 1,
@@ -171,20 +182,34 @@ export default class paradex extends Exchange {
171
182
  'orders/by_client_id/{client_id}': 1,
172
183
  'orders/{order_id}': 1,
173
184
  'points_data/{market}/{program}': 1,
185
+ 'referrals/qr-code': 1,
174
186
  'referrals/summary': 1,
175
187
  'transfers': 1,
188
+ 'algo/orders': 1,
189
+ 'algo/orders-history': 1,
190
+ 'algo/orders/{algo_id}': 1,
191
+ 'vaults/account-summary': 1,
176
192
  },
177
193
  'post': {
194
+ 'account/margin/{market}': 1,
195
+ 'account/profile/max_slippage': 1,
178
196
  'account/profile/referral_code': 1,
179
197
  'account/profile/username': 1,
180
198
  'auth': 1,
181
199
  'onboarding': 1,
182
200
  'orders': 1,
201
+ 'orders/batch': 1,
202
+ 'algo/orders': 1,
203
+ 'vaults': 1,
204
+ },
205
+ 'put': {
206
+ 'orders/{order_id}': 1,
183
207
  },
184
208
  'delete': {
185
209
  'orders': 1,
186
210
  'orders/by_client_id/{client_id}': 1,
187
211
  'orders/{order_id}': 1,
212
+ 'algo/orders/{algo_id}': 1,
188
213
  },
189
214
  },
190
215
  },
@@ -2123,6 +2148,149 @@ export default class paradex extends Exchange {
2123
2148
  };
2124
2149
  return this.safeString(statuses, status, status);
2125
2150
  }
2151
+ /**
2152
+ * @method
2153
+ * @name paradex#fetchMarginMode
2154
+ * @description fetches the margin mode of a specific symbol
2155
+ * @see https://docs.api.testnet.paradex.trade/#get-account-margin-configuration
2156
+ * @param {string} symbol unified symbol of the market the order was made in
2157
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2158
+ * @returns {object} a [margin mode structure]{@link https://docs.ccxt.com/#/?id=margin-mode-structure}
2159
+ */
2160
+ async fetchMarginMode(symbol, params = {}) {
2161
+ await this.authenticateRest();
2162
+ await this.loadMarkets();
2163
+ const market = this.market(symbol);
2164
+ const request = {
2165
+ 'market': market['id'],
2166
+ };
2167
+ const response = await this.privateGetAccountMargin(this.extend(request, params));
2168
+ //
2169
+ // {
2170
+ // "account": "0x6343248026a845b39a8a73fbe9c7ef0a841db31ed5c61ec1446aa9d25e54dbc",
2171
+ // "configs": [
2172
+ // {
2173
+ // "market": "SOL-USD-PERP",
2174
+ // "leverage": 50,
2175
+ // "margin_type": "CROSS"
2176
+ // }
2177
+ // ]
2178
+ // }
2179
+ //
2180
+ const configs = this.safeList(response, 'configs');
2181
+ return this.parseMarginMode(this.safeDict(configs, 0), market);
2182
+ }
2183
+ parseMarginMode(rawMarginMode, market = undefined) {
2184
+ const marketId = this.safeString(rawMarginMode, 'market');
2185
+ market = this.safeMarket(marketId, market);
2186
+ const marginMode = this.safeStringLower(rawMarginMode, 'margin_type');
2187
+ return {
2188
+ 'info': rawMarginMode,
2189
+ 'symbol': market['symbol'],
2190
+ 'marginMode': marginMode,
2191
+ };
2192
+ }
2193
+ /**
2194
+ * @method
2195
+ * @name paradex#setMarginMode
2196
+ * @description set margin mode to 'cross' or 'isolated'
2197
+ * @see https://docs.api.testnet.paradex.trade/#set-margin-configuration
2198
+ * @param {string} marginMode 'cross' or 'isolated'
2199
+ * @param {string} symbol unified market symbol
2200
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2201
+ * @param {float} [params.leverage] the rate of leverage
2202
+ * @returns {object} response from the exchange
2203
+ */
2204
+ async setMarginMode(marginMode, symbol = undefined, params = {}) {
2205
+ this.checkRequiredArgument('setMarginMode', symbol, 'symbol');
2206
+ await this.authenticateRest();
2207
+ await this.loadMarkets();
2208
+ const market = this.market(symbol);
2209
+ let leverage = undefined;
2210
+ [leverage, params] = this.handleOptionAndParams(params, 'setMarginMode', 'leverage', 1);
2211
+ const request = {
2212
+ 'market': market['id'],
2213
+ 'leverage': leverage,
2214
+ 'margin_type': this.encodeMarginMode(marginMode),
2215
+ };
2216
+ return await this.privatePostAccountMarginMarket(this.extend(request, params));
2217
+ }
2218
+ /**
2219
+ * @method
2220
+ * @name paradex#fetchLeverage
2221
+ * @description fetch the set leverage for a market
2222
+ * @see https://docs.api.testnet.paradex.trade/#get-account-margin-configuration
2223
+ * @param {string} symbol unified market symbol
2224
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2225
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
2226
+ */
2227
+ async fetchLeverage(symbol, params = {}) {
2228
+ await this.authenticateRest();
2229
+ await this.loadMarkets();
2230
+ const market = this.market(symbol);
2231
+ const request = {
2232
+ 'market': market['id'],
2233
+ };
2234
+ const response = await this.privateGetAccountMargin(this.extend(request, params));
2235
+ //
2236
+ // {
2237
+ // "account": "0x6343248026a845b39a8a73fbe9c7ef0a841db31ed5c61ec1446aa9d25e54dbc",
2238
+ // "configs": [
2239
+ // {
2240
+ // "market": "SOL-USD-PERP",
2241
+ // "leverage": 50,
2242
+ // "margin_type": "CROSS"
2243
+ // }
2244
+ // ]
2245
+ // }
2246
+ //
2247
+ const configs = this.safeList(response, 'configs');
2248
+ return this.parseLeverage(this.safeDict(configs, 0), market);
2249
+ }
2250
+ parseLeverage(leverage, market = undefined) {
2251
+ const marketId = this.safeString(leverage, 'market');
2252
+ market = this.safeMarket(marketId, market);
2253
+ const marginMode = this.safeStringLower(leverage, 'margin_type');
2254
+ return {
2255
+ 'info': leverage,
2256
+ 'symbol': this.safeSymbol(marketId, market),
2257
+ 'marginMode': marginMode,
2258
+ 'longLeverage': this.safeInteger(leverage, 'leverage'),
2259
+ 'shortLeverage': this.safeInteger(leverage, 'leverage'),
2260
+ };
2261
+ }
2262
+ encodeMarginMode(mode) {
2263
+ const modes = {
2264
+ 'cross': 'CROSS',
2265
+ 'isolated': 'ISOLATED',
2266
+ };
2267
+ return this.safeString(modes, mode, mode);
2268
+ }
2269
+ /**
2270
+ * @method
2271
+ * @name paradex#setLeverage
2272
+ * @description set the level of leverage for a market
2273
+ * @see https://docs.api.testnet.paradex.trade/#set-margin-configuration
2274
+ * @param {float} leverage the rate of leverage
2275
+ * @param {string} [symbol] unified market symbol (is mandatory for swap markets)
2276
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2277
+ * @param {string} [params.marginMode] 'cross' or 'isolated'
2278
+ * @returns {object} response from the exchange
2279
+ */
2280
+ async setLeverage(leverage, symbol = undefined, params = {}) {
2281
+ this.checkRequiredArgument('setLeverage', symbol, 'symbol');
2282
+ await this.authenticateRest();
2283
+ await this.loadMarkets();
2284
+ const market = this.market(symbol);
2285
+ let marginMode = undefined;
2286
+ [marginMode, params] = this.handleMarginModeAndParams('setLeverage', params, 'cross');
2287
+ const request = {
2288
+ 'market': market['id'],
2289
+ 'leverage': leverage,
2290
+ 'margin_type': this.encodeMarginMode(marginMode),
2291
+ };
2292
+ return await this.privatePostAccountMarginMarket(this.extend(request, params));
2293
+ }
2126
2294
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
2127
2295
  let url = this.implodeHostname(this.urls['api'][this.version]) + '/' + this.implodeParams(path, params);
2128
2296
  const query = this.omit(params, this.extractParams(path));
@@ -289,7 +289,7 @@ export default class phemex extends Exchange {
289
289
  * @see https://phemex-docs.github.io/#query-account-positions-with-unrealized-pnl
290
290
  * @param {string[]} [symbols] list of unified market symbols
291
291
  * @param {object} [params] extra parameters specific to the exchange API endpoint
292
- * @param {string} [params.code] the currency code to fetch positions for, USD, BTC or USDT, USD is the default
292
+ * @param {string} [params.code] the currency code to fetch positions for, USD, BTC or USDT, USDT is the default
293
293
  * @param {string} [params.method] *USDT contracts only* 'privateGetGAccountsAccountPositions' or 'privateGetAccountsPositions' default is 'privateGetGAccountsAccountPositions'
294
294
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
295
295
  */
package/js/src/phemex.js CHANGED
@@ -3798,7 +3798,7 @@ export default class phemex extends Exchange {
3798
3798
  * @see https://phemex-docs.github.io/#query-account-positions-with-unrealized-pnl
3799
3799
  * @param {string[]} [symbols] list of unified market symbols
3800
3800
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3801
- * @param {string} [params.code] the currency code to fetch positions for, USD, BTC or USDT, USD is the default
3801
+ * @param {string} [params.code] the currency code to fetch positions for, USD, BTC or USDT, USDT is the default
3802
3802
  * @param {string} [params.method] *USDT contracts only* 'privateGetGAccountsAccountPositions' or 'privateGetAccountsPositions' default is 'privateGetGAccountsAccountPositions'
3803
3803
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
3804
3804
  */
@@ -3806,7 +3806,7 @@ export default class phemex extends Exchange {
3806
3806
  await this.loadMarkets();
3807
3807
  symbols = this.marketSymbols(symbols);
3808
3808
  let subType = undefined;
3809
- let code = this.safeString2(params, 'currency', 'code', 'USD');
3809
+ let code = this.safeString2(params, 'currency', 'code', 'USDT');
3810
3810
  params = this.omit(params, ['currency', 'code']);
3811
3811
  let settle = undefined;
3812
3812
  let market = undefined;
@@ -125,6 +125,7 @@ export default class tradeogre extends Exchange {
125
125
  'orders/{market}': 1,
126
126
  'ticker/{market}': 1,
127
127
  'history/{market}': 1,
128
+ 'chart/{interval}/{market}/{timestamp}': 1,
128
129
  'chart/{interval}/{market}': 1,
129
130
  },
130
131
  },
@@ -417,15 +418,15 @@ export default class tradeogre extends Exchange {
417
418
  'ask': this.safeString(ticker, 'ask'),
418
419
  'askVolume': undefined,
419
420
  'vwap': undefined,
420
- 'open': this.safeString(ticker, 'open'),
421
- 'close': undefined,
421
+ 'open': this.safeString(ticker, 'initialprice'),
422
+ 'close': this.safeString(ticker, 'price'),
422
423
  'last': undefined,
423
424
  'previousClose': undefined,
424
425
  'change': undefined,
425
426
  'percentage': undefined,
426
427
  'average': undefined,
427
- 'baseVolume': this.safeString(ticker, 'volume'),
428
- 'quoteVolume': undefined,
428
+ 'baseVolume': undefined,
429
+ 'quoteVolume': this.safeString(ticker, 'volume'),
429
430
  'info': ticker,
430
431
  }, market);
431
432
  }
@@ -448,12 +449,16 @@ export default class tradeogre extends Exchange {
448
449
  'market': market['id'],
449
450
  'interval': this.safeString(this.timeframes, timeframe, timeframe),
450
451
  };
452
+ let response = undefined;
451
453
  const until = this.safeInteger(params, 'until');
452
454
  if (until !== undefined) {
453
455
  params = this.omit(params, 'until');
454
- request['timestamp'] = until;
456
+ request['timestamp'] = this.parseToInt(until / 1000);
457
+ response = await this.publicGetChartIntervalMarketTimestamp(this.extend(request, params));
458
+ }
459
+ else {
460
+ response = await this.publicGetChartIntervalMarket(this.extend(request, params));
455
461
  }
456
- const response = await this.publicGetChartIntervalMarket(this.extend(request, params));
457
462
  //
458
463
  // [
459
464
  // [
@@ -482,9 +487,9 @@ export default class tradeogre extends Exchange {
482
487
  return [
483
488
  this.safeTimestamp(ohlcv, 0),
484
489
  this.safeNumber(ohlcv, 1),
490
+ this.safeNumber(ohlcv, 2),
485
491
  this.safeNumber(ohlcv, 3),
486
492
  this.safeNumber(ohlcv, 4),
487
- this.safeNumber(ohlcv, 2),
488
493
  this.safeNumber(ohlcv, 5),
489
494
  ];
490
495
  }
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/whitebit.js';
2
- import type { TransferEntry, Balances, Currency, Int, Market, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, Num, Currencies, TradingFees, Dict, int, FundingRate, FundingRates, DepositAddress, Conversion, BorrowInterest, FundingHistory } from './base/types.js';
2
+ import type { TransferEntry, Balances, Currency, Int, Market, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, Num, Currencies, TradingFees, Dict, int, FundingRate, FundingRates, DepositAddress, Conversion, BorrowInterest, FundingHistory, Position } from './base/types.js';
3
3
  /**
4
4
  * @class whitebit
5
5
  * @augments Exchange
@@ -490,6 +490,40 @@ export default class whitebit extends Exchange {
490
490
  */
491
491
  fetchConvertTradeHistory(code?: Str, since?: Int, limit?: Int, params?: {}): Promise<Conversion[]>;
492
492
  parseConversion(conversion: Dict, fromCurrency?: Currency, toCurrency?: Currency): Conversion;
493
+ /**
494
+ * @method
495
+ * @name whitebit#fetchPositionHistory
496
+ * @description fetches historical positions
497
+ * @see https://docs.whitebit.com/private/http-trade-v4/#positions-history
498
+ * @param {string} symbol unified contract symbol
499
+ * @param {int} [since] the earliest time in ms to fetch positions for
500
+ * @param {int} [limit] the maximum amount of records to fetch
501
+ * @param {object} [params] extra parameters specific to the exchange api endpoint
502
+ * @param {int} [params.positionId] the id of the requested position
503
+ * @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
504
+ */
505
+ fetchPositionHistory(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Position[]>;
506
+ /**
507
+ * @method
508
+ * @name whitebit#fetchPositions
509
+ * @description fetch all open positions
510
+ * @see https://docs.whitebit.com/private/http-trade-v4/#open-positions
511
+ * @param {string[]} [symbols] list of unified market symbols
512
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
513
+ * @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
514
+ */
515
+ fetchPositions(symbols?: Strings, params?: {}): Promise<Position[]>;
516
+ /**
517
+ * @method
518
+ * @name whitebit#fetchPosition
519
+ * @description fetch data on a single open contract trade position
520
+ * @see https://docs.whitebit.com/private/http-trade-v4/#open-positions
521
+ * @param {string} symbol unified market symbol of the market the position is held in
522
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
523
+ * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
524
+ */
525
+ fetchPosition(symbol: string, params?: {}): Promise<Position>;
526
+ parsePosition(position: Dict, market?: Market): Position;
493
527
  isFiat(currency: string): boolean;
494
528
  nonce(): number;
495
529
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
@@ -22,7 +22,7 @@ export default class whitebit extends Exchange {
22
22
  'CORS': undefined,
23
23
  'spot': true,
24
24
  'margin': true,
25
- 'swap': false,
25
+ 'swap': true,
26
26
  'future': false,
27
27
  'option': false,
28
28
  'cancelAllOrders': true,
@@ -72,7 +72,10 @@ export default class whitebit extends Exchange {
72
72
  'fetchOpenOrders': true,
73
73
  'fetchOrderBook': true,
74
74
  'fetchOrderTrades': true,
75
+ 'fetchPosition': true,
76
+ 'fetchPositionHistory': true,
75
77
  'fetchPositionMode': false,
78
+ 'fetchPositions': true,
76
79
  'fetchPremiumIndexOHLCV': false,
77
80
  'fetchStatus': true,
78
81
  'fetchTicker': true,
@@ -2958,6 +2961,213 @@ export default class whitebit extends Exchange {
2958
2961
  'fee': undefined,
2959
2962
  };
2960
2963
  }
2964
+ /**
2965
+ * @method
2966
+ * @name whitebit#fetchPositionHistory
2967
+ * @description fetches historical positions
2968
+ * @see https://docs.whitebit.com/private/http-trade-v4/#positions-history
2969
+ * @param {string} symbol unified contract symbol
2970
+ * @param {int} [since] the earliest time in ms to fetch positions for
2971
+ * @param {int} [limit] the maximum amount of records to fetch
2972
+ * @param {object} [params] extra parameters specific to the exchange api endpoint
2973
+ * @param {int} [params.positionId] the id of the requested position
2974
+ * @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
2975
+ */
2976
+ async fetchPositionHistory(symbol, since = undefined, limit = undefined, params = {}) {
2977
+ await this.loadMarkets();
2978
+ const market = this.market(symbol);
2979
+ let request = {
2980
+ 'market': market['id'],
2981
+ };
2982
+ if (since !== undefined) {
2983
+ request['startDate'] = since;
2984
+ }
2985
+ if (limit !== undefined) {
2986
+ request['limit'] = since;
2987
+ }
2988
+ [request, params] = this.handleUntilOption('endDate', request, params);
2989
+ const response = await this.v4PrivatePostCollateralAccountPositionsHistory(this.extend(request, params));
2990
+ //
2991
+ // [
2992
+ // {
2993
+ // "positionId": 479975679,
2994
+ // "market": "BTC_PERP",
2995
+ // "openDate": 1741941025.309887,
2996
+ // "modifyDate": 1741941025.309887,
2997
+ // "amount": "0.001",
2998
+ // "basePrice": "82498.7",
2999
+ // "realizedFunding": "0",
3000
+ // "liquidationPrice": "0",
3001
+ // "liquidationState": null,
3002
+ // "orderDetail": {
3003
+ // "id": 1224727949521,
3004
+ // "tradeAmount": "0.001",
3005
+ // "price": "82498.7",
3006
+ // "tradeFee": "0.028874545",
3007
+ // "fundingFee": "0",
3008
+ // "realizedPnl": "-0.028874545"
3009
+ // }
3010
+ // }
3011
+ // ]
3012
+ //
3013
+ const positions = this.parsePositions(response);
3014
+ return this.filterBySymbolSinceLimit(positions, symbol, since, limit);
3015
+ }
3016
+ /**
3017
+ * @method
3018
+ * @name whitebit#fetchPositions
3019
+ * @description fetch all open positions
3020
+ * @see https://docs.whitebit.com/private/http-trade-v4/#open-positions
3021
+ * @param {string[]} [symbols] list of unified market symbols
3022
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3023
+ * @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
3024
+ */
3025
+ async fetchPositions(symbols = undefined, params = {}) {
3026
+ await this.loadMarkets();
3027
+ symbols = this.marketSymbols(symbols);
3028
+ const response = await this.v4PrivatePostCollateralAccountPositionsOpen(params);
3029
+ //
3030
+ // [
3031
+ // {
3032
+ // "positionId": 479975679,
3033
+ // "market": "BTC_PERP",
3034
+ // "openDate": 1741941025.3098869,
3035
+ // "modifyDate": 1741941025.3098869,
3036
+ // "amount": "0.001",
3037
+ // "basePrice": "82498.7",
3038
+ // "liquidationPrice": "70177.2",
3039
+ // "pnl": "0",
3040
+ // "pnlPercent": "0.00",
3041
+ // "margin": "4.2",
3042
+ // "freeMargin": "9.9",
3043
+ // "funding": "0",
3044
+ // "unrealizedFunding": "0",
3045
+ // "liquidationState": null,
3046
+ // "tpsl": null
3047
+ // }
3048
+ // ]
3049
+ //
3050
+ return this.parsePositions(response, symbols);
3051
+ }
3052
+ /**
3053
+ * @method
3054
+ * @name whitebit#fetchPosition
3055
+ * @description fetch data on a single open contract trade position
3056
+ * @see https://docs.whitebit.com/private/http-trade-v4/#open-positions
3057
+ * @param {string} symbol unified market symbol of the market the position is held in
3058
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3059
+ * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
3060
+ */
3061
+ async fetchPosition(symbol, params = {}) {
3062
+ await this.loadMarkets();
3063
+ const market = this.market(symbol);
3064
+ const request = {
3065
+ 'symbol': market['id'],
3066
+ };
3067
+ const response = await this.v4PrivatePostCollateralAccountPositionsOpen(this.extend(request, params));
3068
+ //
3069
+ // [
3070
+ // {
3071
+ // "positionId": 479975679,
3072
+ // "market": "BTC_PERP",
3073
+ // "openDate": 1741941025.3098869,
3074
+ // "modifyDate": 1741941025.3098869,
3075
+ // "amount": "0.001",
3076
+ // "basePrice": "82498.7",
3077
+ // "liquidationPrice": "70177.2",
3078
+ // "pnl": "0",
3079
+ // "pnlPercent": "0.00",
3080
+ // "margin": "4.2",
3081
+ // "freeMargin": "9.9",
3082
+ // "funding": "0",
3083
+ // "unrealizedFunding": "0",
3084
+ // "liquidationState": null,
3085
+ // "tpsl": null
3086
+ // }
3087
+ // ]
3088
+ //
3089
+ const data = this.safeDict(response, 0, {});
3090
+ return this.parsePosition(data, market);
3091
+ }
3092
+ parsePosition(position, market = undefined) {
3093
+ //
3094
+ // fetchPosition, fetchPositions
3095
+ //
3096
+ // {
3097
+ // "positionId": 479975679,
3098
+ // "market": "BTC_PERP",
3099
+ // "openDate": 1741941025.3098869,
3100
+ // "modifyDate": 1741941025.3098869,
3101
+ // "amount": "0.001",
3102
+ // "basePrice": "82498.7",
3103
+ // "liquidationPrice": "70177.2",
3104
+ // "pnl": "0",
3105
+ // "pnlPercent": "0.00",
3106
+ // "margin": "4.2",
3107
+ // "freeMargin": "9.9",
3108
+ // "funding": "0",
3109
+ // "unrealizedFunding": "0",
3110
+ // "liquidationState": null,
3111
+ // "tpsl": null
3112
+ // }
3113
+ //
3114
+ // fetchPositionHistory
3115
+ //
3116
+ // {
3117
+ // "positionId": 479975679,
3118
+ // "market": "BTC_PERP",
3119
+ // "openDate": 1741941025.309887,
3120
+ // "modifyDate": 1741941025.309887,
3121
+ // "amount": "0.001",
3122
+ // "basePrice": "82498.7",
3123
+ // "realizedFunding": "0",
3124
+ // "liquidationPrice": "0",
3125
+ // "liquidationState": null,
3126
+ // "orderDetail": {
3127
+ // "id": 1224727949521,
3128
+ // "tradeAmount": "0.001",
3129
+ // "price": "82498.7",
3130
+ // "tradeFee": "0.028874545",
3131
+ // "fundingFee": "0",
3132
+ // "realizedPnl": "-0.028874545"
3133
+ // }
3134
+ // }
3135
+ //
3136
+ const marketId = this.safeString(position, 'market');
3137
+ const timestamp = this.safeTimestamp(position, 'openDate');
3138
+ const tpsl = this.safeDict(position, 'tpsl', {});
3139
+ const orderDetail = this.safeDict(position, 'orderDetail', {});
3140
+ return this.safePosition({
3141
+ 'info': position,
3142
+ 'id': this.safeString(position, 'positionId'),
3143
+ 'symbol': this.safeSymbol(marketId, market),
3144
+ 'notional': undefined,
3145
+ 'marginMode': undefined,
3146
+ 'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
3147
+ 'entryPrice': this.safeNumber(position, 'basePrice'),
3148
+ 'unrealizedPnl': this.safeNumber(position, 'pnl'),
3149
+ 'realizedPnl': this.safeNumber(orderDetail, 'realizedPnl'),
3150
+ 'percentage': this.safeNumber(position, 'pnlPercent'),
3151
+ 'contracts': undefined,
3152
+ 'contractSize': undefined,
3153
+ 'markPrice': undefined,
3154
+ 'lastPrice': undefined,
3155
+ 'side': undefined,
3156
+ 'hedged': undefined,
3157
+ 'timestamp': timestamp,
3158
+ 'datetime': this.iso8601(timestamp),
3159
+ 'lastUpdateTimestamp': this.safeTimestamp(position, 'modifyDate'),
3160
+ 'maintenanceMargin': undefined,
3161
+ 'maintenanceMarginPercentage': undefined,
3162
+ 'collateral': this.safeNumber(position, 'margin'),
3163
+ 'initialMargin': undefined,
3164
+ 'initialMarginPercentage': undefined,
3165
+ 'leverage': undefined,
3166
+ 'marginRatio': undefined,
3167
+ 'stopLossPrice': this.safeNumber(tpsl, 'stopLoss'),
3168
+ 'takeProfitPrice': this.safeNumber(tpsl, 'takeProfit'),
3169
+ });
3170
+ }
2961
3171
  isFiat(currency) {
2962
3172
  const fiatCurrencies = this.safeValue(this.options, 'fiatCurrencies', []);
2963
3173
  return this.inArray(currency, fiatCurrencies);