ccxt 4.1.74 → 4.1.75

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.
@@ -752,32 +752,34 @@ class poloniex extends poloniex$1 {
752
752
  let withdrawAvailable = this.safeValue(result[code], 'withdraw');
753
753
  withdrawAvailable = (withdrawEnabled) ? withdrawEnabled : withdrawAvailable;
754
754
  const networks = this.safeValue(result[code], 'networks', {});
755
- networks[networkCode] = {
756
- 'info': currency,
757
- 'id': networkId,
758
- 'network': networkCode,
759
- 'currencyId': id,
760
- 'numericId': numericId,
761
- 'deposit': depositEnabled,
762
- 'withdraw': withdrawEnabled,
763
- 'active': active,
764
- 'fee': this.parseNumber(feeString),
765
- 'precision': undefined,
766
- 'limits': {
767
- 'amount': {
768
- 'min': undefined,
769
- 'max': undefined,
770
- },
771
- 'withdraw': {
772
- 'min': undefined,
773
- 'max': undefined,
774
- },
775
- 'deposit': {
776
- 'min': undefined,
777
- 'max': undefined,
755
+ if (networkCode !== undefined) {
756
+ networks[networkCode] = {
757
+ 'info': currency,
758
+ 'id': networkId,
759
+ 'network': networkCode,
760
+ 'currencyId': id,
761
+ 'numericId': numericId,
762
+ 'deposit': depositEnabled,
763
+ 'withdraw': withdrawEnabled,
764
+ 'active': active,
765
+ 'fee': this.parseNumber(feeString),
766
+ 'precision': undefined,
767
+ 'limits': {
768
+ 'amount': {
769
+ 'min': undefined,
770
+ 'max': undefined,
771
+ },
772
+ 'withdraw': {
773
+ 'min': undefined,
774
+ 'max': undefined,
775
+ },
776
+ 'deposit': {
777
+ 'min': undefined,
778
+ 'max': undefined,
779
+ },
778
780
  },
779
- },
780
- };
781
+ };
782
+ }
781
783
  result[code]['networks'] = networks;
782
784
  const info = this.safeValue(result[code], 'info', []);
783
785
  const rawInfo = {};
@@ -23,6 +23,7 @@ class binance extends binance$1 {
23
23
  'watchOrderBook': true,
24
24
  'watchOrderBookForSymbols': true,
25
25
  'watchOrders': true,
26
+ 'watchOrdersForSymbols': true,
26
27
  'watchPositions': true,
27
28
  'watchTicker': true,
28
29
  'watchTickers': true,
@@ -2062,6 +2063,7 @@ class binance extends binance$1 {
2062
2063
  /**
2063
2064
  * @method
2064
2065
  * @name binance#watchOrders
2066
+ * @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
2065
2067
  * @description watches information on multiple orders made by the user
2066
2068
  * @param {string} symbol unified market symbol of the market orders were made in
2067
2069
  * @param {int} [since] the earliest time in ms to fetch orders for
@@ -2075,7 +2077,7 @@ class binance extends binance$1 {
2075
2077
  if (symbol !== undefined) {
2076
2078
  market = this.market(symbol);
2077
2079
  symbol = market['symbol'];
2078
- messageHash += ':' + symbol;
2080
+ messageHash += '::' + symbol;
2079
2081
  }
2080
2082
  let type = undefined;
2081
2083
  [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
@@ -2098,11 +2100,63 @@ class binance extends binance$1 {
2098
2100
  this.setBalanceCache(client, type);
2099
2101
  this.setPositionsCache(client, type);
2100
2102
  const message = undefined;
2101
- const orders = await this.watch(url, messageHash, message, type);
2103
+ const newOrder = await this.watch(url, messageHash, message, type);
2102
2104
  if (this.newUpdates) {
2103
- limit = orders.getLimit(symbol, limit);
2105
+ return newOrder;
2104
2106
  }
2105
- return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
2107
+ return this.filterBySymbolSinceLimit(this.orders, symbol, since, limit, true);
2108
+ }
2109
+ async watchOrdersForSymbols(symbols = undefined, since = undefined, limit = undefined, params = {}) {
2110
+ /**
2111
+ * @method
2112
+ * @name binance#watchOrdersForSymbols
2113
+ * @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
2114
+ * @description watches information on multiple orders made by the user
2115
+ * @param {string[]} symbols unified symbol of the market to fetch orders for
2116
+ * @param {int} [since] the earliest time in ms to fetch orders for
2117
+ * @param {int} [limit] the maximum number of trade structures to retrieve
2118
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2119
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2120
+ */
2121
+ let marginMode = undefined;
2122
+ [marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
2123
+ const isIsolatedMargin = (marginMode === 'isolated');
2124
+ if (isIsolatedMargin) {
2125
+ throw new errors.NotSupported(this.id + ' watchOrdersForSymbols does not support isolated margin markets, use watchOrders instead');
2126
+ }
2127
+ await this.loadMarkets();
2128
+ let type = undefined;
2129
+ const market = this.getMarketFromSymbols(symbols);
2130
+ [type, params] = this.handleMarketTypeAndParams('watchOrdersForSymbols', market, params);
2131
+ symbols = this.marketSymbols(symbols, type, true, true, true);
2132
+ let messageHash = 'orders';
2133
+ if (symbols !== undefined) {
2134
+ messageHash = messageHash + '::' + symbols.join(',');
2135
+ }
2136
+ let subType = undefined;
2137
+ [subType, params] = this.handleSubTypeAndParams('watchOrdersForSymbols', market, params);
2138
+ if (this.isLinear(type, subType)) {
2139
+ type = 'future';
2140
+ }
2141
+ else if (this.isInverse(type, subType)) {
2142
+ type = 'delivery';
2143
+ }
2144
+ params = this.extend(params, { 'type': type });
2145
+ await this.authenticate(params);
2146
+ let urlType = type;
2147
+ if (type === 'margin') {
2148
+ urlType = 'spot'; // spot-margin shares the same stream as regular spot
2149
+ }
2150
+ const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2151
+ const client = this.client(url);
2152
+ this.setBalanceCache(client, type);
2153
+ this.setPositionsCache(client, type);
2154
+ const message = undefined;
2155
+ const newOrders = await this.watch(url, messageHash, message, type);
2156
+ if (this.newUpdates) {
2157
+ return newOrders;
2158
+ }
2159
+ return this.filterBySymbolsSinceLimit(this.orders, symbols, since, limit, true);
2106
2160
  }
2107
2161
  parseWsOrder(order, market = undefined) {
2108
2162
  //
@@ -2733,7 +2787,6 @@ class binance extends binance$1 {
2733
2787
  }
2734
2788
  }
2735
2789
  handleOrder(client, message) {
2736
- const messageHash = 'orders';
2737
2790
  const parsed = this.parseWsOrder(message);
2738
2791
  const symbol = this.safeString(parsed, 'symbol');
2739
2792
  const orderId = this.safeString(parsed, 'id');
@@ -2762,9 +2815,8 @@ class binance extends binance$1 {
2762
2815
  }
2763
2816
  }
2764
2817
  cachedOrders.append(parsed);
2765
- client.resolve(this.orders, messageHash);
2766
- const messageHashSymbol = messageHash + ':' + symbol;
2767
- client.resolve(this.orders, messageHashSymbol);
2818
+ this.resolvePromiseIfMessagehashMatches(client, 'orders::', symbol, parsed);
2819
+ client.resolve(parsed, 'orders');
2768
2820
  }
2769
2821
  }
2770
2822
  handleAcountUpdate(client, message) {
@@ -248,8 +248,8 @@ class coinbasepro extends coinbasepro$1 {
248
248
  * @param {object} [params] extra parameters specific to the exchange API endpoint
249
249
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
250
250
  */
251
- symbols = this.marketSymbols(symbols, undefined, false);
252
251
  await this.loadMarkets();
252
+ symbols = this.marketSymbols(symbols, undefined, false);
253
253
  const name = 'user';
254
254
  const messageHash = 'multipleOrders::';
255
255
  const authentication = this.authenticate();
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
7
- declare const version = "4.1.73";
7
+ declare const version = "4.1.74";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.1.74';
41
+ const version = '4.1.75';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -4685,6 +4685,10 @@ export default class Exchange {
4685
4685
  if (cursorValue === undefined) {
4686
4686
  break;
4687
4687
  }
4688
+ const lastTimestamp = this.safeInteger(last, 'timestamp');
4689
+ if (lastTimestamp !== undefined && lastTimestamp < since) {
4690
+ break;
4691
+ }
4688
4692
  }
4689
4693
  catch (e) {
4690
4694
  errors += 1;
@@ -4737,10 +4741,10 @@ export default class Exchange {
4737
4741
  const first = this.safeValue(result, 0);
4738
4742
  if (first !== undefined) {
4739
4743
  if ('timestamp' in first) {
4740
- return this.sortBy(result, 'timestamp');
4744
+ return this.sortBy(result, 'timestamp', true);
4741
4745
  }
4742
4746
  if ('id' in first) {
4743
- return this.sortBy(result, 'id');
4747
+ return this.sortBy(result, 'id', true);
4744
4748
  }
4745
4749
  }
4746
4750
  return result;
@@ -250,23 +250,20 @@ export default class Client {
250
250
  // MessageEvent {isTrusted: true, data: "{"e":"depthUpdate","E":1581358737706,"s":"ETHBTC",…"0.06200000"]],"a":[["0.02261300","0.00000000"]]}", origin: "wss://stream.binance.com:9443", lastEventId: "", source: null, …}
251
251
  let message = messageEvent.data;
252
252
  let arrayBuffer;
253
- if (this.gunzip || this.inflate) {
254
- if (typeof message === 'string') {
255
- arrayBuffer = utf8.decode(message);
256
- }
257
- else {
253
+ if (typeof message !== 'string') {
254
+ if (this.gunzip || this.inflate) {
258
255
  arrayBuffer = new Uint8Array(message.buffer.slice(message.byteOffset, message.byteOffset + message.byteLength));
256
+ if (this.gunzip) {
257
+ arrayBuffer = gunzipSync(arrayBuffer);
258
+ }
259
+ else if (this.inflate) {
260
+ arrayBuffer = inflateSync(arrayBuffer);
261
+ }
262
+ message = utf8.encode(arrayBuffer);
259
263
  }
260
- if (this.gunzip) {
261
- arrayBuffer = gunzipSync(arrayBuffer);
262
- }
263
- else if (this.inflate) {
264
- arrayBuffer = inflateSync(arrayBuffer);
264
+ else {
265
+ message = message.toString();
265
266
  }
266
- message = utf8.encode(arrayBuffer);
267
- }
268
- if (typeof message !== 'string') {
269
- message = message.toString();
270
267
  }
271
268
  try {
272
269
  if (isJsonEncodedObject(message)) {
@@ -22,6 +22,7 @@ export default class bigone extends Exchange {
22
22
  fetchBalance(params?: {}): Promise<Balances>;
23
23
  parseType(type: string): string;
24
24
  parseOrder(order: any, market?: Market): Order;
25
+ createMarketBuyOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
25
26
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
26
27
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<Order>;
27
28
  cancelAllOrders(symbol?: Str, params?: {}): Promise<any>;
package/js/src/bigone.js CHANGED
@@ -33,6 +33,8 @@ export default class bigone extends Exchange {
33
33
  'option': undefined,
34
34
  'cancelAllOrders': true,
35
35
  'cancelOrder': true,
36
+ 'createMarketBuyOrderWithCost': true,
37
+ 'createMarketSellOrderWithCost': false,
36
38
  'createOrder': true,
37
39
  'createPostOnlyOrder': true,
38
40
  'createStopLimitOrder': true,
@@ -1155,6 +1157,20 @@ export default class bigone extends Exchange {
1155
1157
  'trades': undefined,
1156
1158
  }, market);
1157
1159
  }
1160
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1161
+ /**
1162
+ * @method
1163
+ * @name bigone#createMarketBuyOrderWithCost
1164
+ * @see https://open.big.one/docs/spot_orders.html#create-order
1165
+ * @description create a market buy order by providing the symbol and cost
1166
+ * @param {string} symbol unified symbol of the market to create an order in
1167
+ * @param {float} cost how much you want to trade in units of the quote currency
1168
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1169
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1170
+ */
1171
+ params['createMarketBuyOrderRequiresPrice'] = false;
1172
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1173
+ }
1158
1174
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1159
1175
  /**
1160
1176
  * @method
@@ -1182,7 +1198,7 @@ export default class bigone extends Exchange {
1182
1198
  const requestSide = isBuy ? 'BID' : 'ASK';
1183
1199
  let uppercaseType = type.toUpperCase();
1184
1200
  const isLimit = uppercaseType === 'LIMIT';
1185
- const exchangeSpecificParam = this.safeValue(params, 'post_only');
1201
+ const exchangeSpecificParam = this.safeValue(params, 'post_only', false);
1186
1202
  let postOnly = undefined;
1187
1203
  [postOnly, params] = this.handlePostOnly((uppercaseType === 'MARKET'), exchangeSpecificParam, params);
1188
1204
  const triggerPrice = this.safeStringN(params, ['triggerPrice', 'stopPrice', 'stop_price']);
@@ -1206,21 +1222,34 @@ export default class bigone extends Exchange {
1206
1222
  request['post_only'] = true;
1207
1223
  }
1208
1224
  }
1225
+ request['amount'] = this.amountToPrecision(symbol, amount);
1209
1226
  }
1210
1227
  else {
1211
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice');
1212
- if (createMarketBuyOrderRequiresPrice && (side === 'buy')) {
1213
- if (price === undefined) {
1214
- throw new InvalidOrder(this.id + ' createOrder() requires price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter');
1228
+ if (isBuy) {
1229
+ let createMarketBuyOrderRequiresPrice = true;
1230
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1231
+ const cost = this.safeNumber(params, 'cost');
1232
+ params = this.omit(params, 'cost');
1233
+ if (createMarketBuyOrderRequiresPrice) {
1234
+ if ((price === undefined) && (cost === undefined)) {
1235
+ throw new InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
1236
+ }
1237
+ else {
1238
+ const amountString = this.numberToString(amount);
1239
+ const priceString = this.numberToString(price);
1240
+ const quoteAmount = this.parseToNumeric(Precise.stringMul(amountString, priceString));
1241
+ const costRequest = (cost !== undefined) ? cost : quoteAmount;
1242
+ request['amount'] = this.costToPrecision(symbol, costRequest);
1243
+ }
1215
1244
  }
1216
1245
  else {
1217
- const amountString = this.numberToString(amount);
1218
- const priceString = this.numberToString(price);
1219
- amount = this.parseNumber(Precise.stringMul(amountString, priceString));
1246
+ request['amount'] = this.costToPrecision(symbol, amount);
1220
1247
  }
1221
1248
  }
1249
+ else {
1250
+ request['amount'] = this.amountToPrecision(symbol, amount);
1251
+ }
1222
1252
  }
1223
- request['amount'] = this.amountToPrecision(symbol, amount);
1224
1253
  if (triggerPrice !== undefined) {
1225
1254
  request['stop_price'] = this.priceToPrecision(symbol, triggerPrice);
1226
1255
  request['operator'] = isBuy ? 'GTE' : 'LTE';
package/js/src/bingx.d.ts CHANGED
@@ -61,6 +61,9 @@ export default class bingx extends Exchange {
61
61
  parseBalance(response: any): Balances;
62
62
  fetchPositions(symbols?: Strings, params?: {}): Promise<import("./base/types.js").Position[]>;
63
63
  parsePosition(position: any, market?: Market): import("./base/types.js").Position;
64
+ createMarketOrderWithCost(symbol: string, side: OrderSide, cost: any, params?: {}): Promise<Order>;
65
+ createMarketBuyOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
66
+ createMarketSellOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
64
67
  createOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): any;
65
68
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
66
69
  createOrders(orders: OrderRequest[], params?: {}): Promise<Order[]>;
package/js/src/bingx.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/bingx.js';
9
- import { AuthenticationError, ExchangeNotAvailable, PermissionDenied, ExchangeError, InsufficientFunds, BadRequest, OrderNotFound, DDoSProtection, BadSymbol, InvalidOrder, ArgumentsRequired } from './base/errors.js';
9
+ import { AuthenticationError, ExchangeNotAvailable, PermissionDenied, ExchangeError, InsufficientFunds, BadRequest, OrderNotFound, DDoSProtection, BadSymbol, ArgumentsRequired } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
12
12
  import { DECIMAL_PLACES } from './base/functions/number.js';
@@ -32,6 +32,9 @@ export default class bingx extends Exchange {
32
32
  'cancelAllOrders': true,
33
33
  'cancelOrder': true,
34
34
  'cancelOrders': true,
35
+ 'createMarketBuyOrderWithCost': true,
36
+ 'createMarketOrderWithCost': true,
37
+ 'createMarketSellOrderWithCost': true,
35
38
  'createOrder': true,
36
39
  'createOrders': true,
37
40
  'fetchBalance': true,
@@ -1624,6 +1627,46 @@ export default class bingx extends Exchange {
1624
1627
  'takeProfitPrice': undefined,
1625
1628
  });
1626
1629
  }
1630
+ async createMarketOrderWithCost(symbol, side, cost, params = {}) {
1631
+ /**
1632
+ * @method
1633
+ * @name bingx#createMarketOrderWithCost
1634
+ * @description create a market order by providing the symbol, side and cost
1635
+ * @param {string} symbol unified symbol of the market to create an order in
1636
+ * @param {string} side 'buy' or 'sell'
1637
+ * @param {float} cost how much you want to trade in units of the quote currency
1638
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1639
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1640
+ */
1641
+ params['quoteOrderQty'] = cost;
1642
+ return await this.createOrder(symbol, 'market', side, cost, undefined, params);
1643
+ }
1644
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1645
+ /**
1646
+ * @method
1647
+ * @name bingx#createMarketBuyOrderWithCost
1648
+ * @description create a market buy order by providing the symbol and cost
1649
+ * @param {string} symbol unified symbol of the market to create an order in
1650
+ * @param {float} cost how much you want to trade in units of the quote currency
1651
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1652
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1653
+ */
1654
+ params['quoteOrderQty'] = cost;
1655
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1656
+ }
1657
+ async createMarketSellOrderWithCost(symbol, cost, params = {}) {
1658
+ /**
1659
+ * @method
1660
+ * @name bingx#createMarketSellOrderWithCost
1661
+ * @description create a market sell order by providing the symbol and cost
1662
+ * @param {string} symbol unified symbol of the market to create an order in
1663
+ * @param {float} cost how much you want to trade in units of the quote currency
1664
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1665
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1666
+ */
1667
+ params['quoteOrderQty'] = cost;
1668
+ return await this.createOrder(symbol, 'market', 'sell', cost, undefined, params);
1669
+ }
1627
1670
  createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
1628
1671
  /**
1629
1672
  * @method
@@ -1659,26 +1702,21 @@ export default class bingx extends Exchange {
1659
1702
  if (postOnly || (timeInForce === 'POC')) {
1660
1703
  request['timeInForce'] = 'POC';
1661
1704
  }
1662
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
1663
- if (isMarketOrder && (side === 'buy')) {
1664
- if (createMarketBuyOrderRequiresPrice) {
1665
- if (price === undefined) {
1666
- throw new InvalidOrder(this.id + ' createOrder() requires price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter');
1667
- }
1668
- else {
1669
- const amountString = this.numberToString(amount);
1670
- const priceString = this.numberToString(price);
1671
- const cost = this.parseNumber(Precise.stringMul(amountString, priceString));
1672
- request['quoteOrderQty'] = this.parseToNumeric(this.priceToPrecision(symbol, cost));
1673
- }
1705
+ const cost = this.safeNumber2(params, 'cost', 'quoteOrderQty');
1706
+ params = this.omit(params, 'cost');
1707
+ if (cost !== undefined) {
1708
+ request['quoteOrderQty'] = this.parseToNumeric(this.costToPrecision(symbol, cost));
1709
+ }
1710
+ else {
1711
+ if (market['spot'] && isMarketOrder && (price !== undefined)) {
1712
+ // keep the legacy behavior, to avoid breaking the old spot-market-buying code
1713
+ const calculatedCost = Precise.stringMul(this.numberToString(amount), this.numberToString(price));
1714
+ request['quoteOrderQty'] = this.parseToNumeric(calculatedCost);
1674
1715
  }
1675
1716
  else {
1676
- request['quoteOrderQty'] = this.parseToNumeric(this.priceToPrecision(symbol, amount));
1717
+ request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
1677
1718
  }
1678
1719
  }
1679
- else {
1680
- request['quantity'] = this.parseToNumeric(this.amountToPrecision(symbol, amount));
1681
- }
1682
1720
  if (!isMarketOrder) {
1683
1721
  request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1684
1722
  }
@@ -1753,8 +1791,8 @@ export default class bingx extends Exchange {
1753
1791
  * @method
1754
1792
  * @name bingx#createOrder
1755
1793
  * @description create a trade order
1756
- * @see https://bingx-api.github.io/docs/#/spot/trade-api.html#Create%20an%20Order
1757
- * @see https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Trade%20order
1794
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Create%20an%20Order
1795
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Trade%20order
1758
1796
  * @param {string} symbol unified symbol of the market to create an order in
1759
1797
  * @param {string} type 'market' or 'limit'
1760
1798
  * @param {string} side 'buy' or 'sell'
@@ -1767,6 +1805,7 @@ export default class bingx extends Exchange {
1767
1805
  * @param {float} [params.triggerPrice] *swap only* triggerPrice at which the attached take profit / stop loss order will be triggered
1768
1806
  * @param {float} [params.stopLossPrice] *swap only* stop loss trigger price
1769
1807
  * @param {float} [params.takeProfitPrice] *swap only* take profit trigger price
1808
+ * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount
1770
1809
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1771
1810
  */
1772
1811
  await this.loadMarkets();
@@ -75,6 +75,7 @@ export default class bitmart extends Exchange {
75
75
  parseOrder(order: any, market?: Market): Order;
76
76
  parseOrderSide(side: any): string;
77
77
  parseOrderStatusByType(type: any, status: any): string;
78
+ createMarketBuyOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
78
79
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
79
80
  createSwapOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): any;
80
81
  createSpotOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): any;
package/js/src/bitmart.js CHANGED
@@ -39,6 +39,9 @@ export default class bitmart extends Exchange {
39
39
  'cancelAllOrders': true,
40
40
  'cancelOrder': true,
41
41
  'cancelOrders': false,
42
+ 'createMarketBuyOrderWithCost': true,
43
+ 'createMarketOrderWithCost': false,
44
+ 'createMarketSellOrderWithCost': false,
42
45
  'createOrder': true,
43
46
  'createPostOnlyOrder': true,
44
47
  'createStopLimitOrder': false,
@@ -2164,12 +2167,31 @@ export default class bitmart extends Exchange {
2164
2167
  const statuses = this.safeValue(statusesByType, type, {});
2165
2168
  return this.safeString(statuses, status, status);
2166
2169
  }
2170
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
2171
+ /**
2172
+ * @method
2173
+ * @name bitmart#createMarketBuyOrderWithCost
2174
+ * @description create a market buy order by providing the symbol and cost
2175
+ * @see https://developer-pro.bitmart.com/en/spot/#new-order-v2-signed
2176
+ * @param {string} symbol unified symbol of the market to create an order in
2177
+ * @param {float} cost how much you want to trade in units of the quote currency
2178
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2179
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2180
+ */
2181
+ await this.loadMarkets();
2182
+ const market = this.market(symbol);
2183
+ if (!market['spot']) {
2184
+ throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
2185
+ }
2186
+ params['createMarketBuyOrderRequiresPrice'] = false;
2187
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
2188
+ }
2167
2189
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
2168
2190
  /**
2169
2191
  * @method
2170
2192
  * @name bitmart#createOrder
2171
2193
  * @description create a trade order
2172
- * @see https://developer-pro.bitmart.com/en/spot/#place-spot-order
2194
+ * @see https://developer-pro.bitmart.com/en/spot/#new-order-v2-signed
2173
2195
  * @see https://developer-pro.bitmart.com/en/spot/#place-margin-order
2174
2196
  * @see https://developer-pro.bitmart.com/en/futures/#submit-order-signed
2175
2197
  * @param {string} symbol unified symbol of the market to create an order in
@@ -2346,18 +2368,18 @@ export default class bitmart extends Exchange {
2346
2368
  else if (isMarketOrder) {
2347
2369
  // for market buy it requires the amount of quote currency to spend
2348
2370
  if (side === 'buy') {
2349
- let notional = this.safeNumber(params, 'notional');
2350
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
2371
+ let notional = this.safeNumber2(params, 'cost', 'notional');
2372
+ params = this.omit(params, 'cost');
2373
+ let createMarketBuyOrderRequiresPrice = true;
2374
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
2351
2375
  if (createMarketBuyOrderRequiresPrice) {
2352
- if (price !== undefined) {
2353
- if (notional === undefined) {
2354
- const amountString = this.numberToString(amount);
2355
- const priceString = this.numberToString(price);
2356
- notional = this.parseNumber(Precise.stringMul(amountString, priceString));
2357
- }
2376
+ if ((price === undefined) && (notional === undefined)) {
2377
+ throw new InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument or in the "notional" extra parameter (the exchange-specific behaviour)');
2358
2378
  }
2359
- else if (notional === undefined) {
2360
- throw new InvalidOrder(this.id + " createOrder () requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false and supply the total cost value in the 'amount' argument or in the 'notional' extra parameter (the exchange-specific behaviour)");
2379
+ else {
2380
+ const amountString = this.numberToString(amount);
2381
+ const priceString = this.numberToString(price);
2382
+ notional = this.parseNumber(Precise.stringMul(amountString, priceString));
2361
2383
  }
2362
2384
  }
2363
2385
  else {
package/js/src/gate.js CHANGED
@@ -50,6 +50,7 @@ export default class gate extends Exchange {
50
50
  'subAccounts': 'https://api.gateio.ws/api/v4',
51
51
  'rebate': 'https://api.gateio.ws/api/v4',
52
52
  'earn': 'https://api.gateio.ws/api/v4',
53
+ 'account': 'https://api.gateio.ws/api/v4',
53
54
  },
54
55
  },
55
56
  'test': {
package/js/src/gemini.js CHANGED
@@ -344,26 +344,28 @@ export default class gemini extends Exchange {
344
344
  const networks = {};
345
345
  const networkId = this.safeString(currency, 9);
346
346
  const networkCode = this.networkIdToCode(networkId);
347
- networks[networkCode] = {
348
- 'info': currency,
349
- 'id': networkId,
350
- 'network': networkCode,
351
- 'active': undefined,
352
- 'deposit': undefined,
353
- 'withdraw': undefined,
354
- 'fee': undefined,
355
- 'precision': precision,
356
- 'limits': {
357
- 'deposit': {
358
- 'min': undefined,
359
- 'max': undefined,
360
- },
361
- 'withdraw': {
362
- 'min': undefined,
363
- 'max': undefined,
347
+ if (networkCode !== undefined) {
348
+ networks[networkCode] = {
349
+ 'info': currency,
350
+ 'id': networkId,
351
+ 'network': networkCode,
352
+ 'active': undefined,
353
+ 'deposit': undefined,
354
+ 'withdraw': undefined,
355
+ 'fee': undefined,
356
+ 'precision': precision,
357
+ 'limits': {
358
+ 'deposit': {
359
+ 'min': undefined,
360
+ 'max': undefined,
361
+ },
362
+ 'withdraw': {
363
+ 'min': undefined,
364
+ 'max': undefined,
365
+ },
364
366
  },
365
- },
366
- };
367
+ };
368
+ }
367
369
  result[code] = {
368
370
  'info': currency,
369
371
  'id': id,