ccxt 4.1.83 → 4.1.85

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/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.82";
7
+ declare const version = "4.1.84";
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.83';
41
+ const version = '4.1.85';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -794,6 +794,7 @@ export default class Exchange {
794
794
  fetchFundingHistory(symbol?: string, since?: Int, limit?: Int, params?: {}): Promise<FundingHistory[]>;
795
795
  closePosition(symbol: string, side?: OrderSide, params?: {}): Promise<Order>;
796
796
  closeAllPositions(params?: {}): Promise<Position[]>;
797
+ fetchL3OrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
797
798
  parseLastPrice(price: any, market?: Market): any;
798
799
  fetchDepositAddress(code: string, params?: {}): Promise<any>;
799
800
  account(): Account;
@@ -3702,6 +3702,9 @@ export default class Exchange {
3702
3702
  async closeAllPositions(params = {}) {
3703
3703
  throw new NotSupported(this.id + ' closeAllPositions() is not supported yet');
3704
3704
  }
3705
+ async fetchL3OrderBook(symbol, limit = undefined, params = {}) {
3706
+ throw new BadRequest(this.id + ' fetchL3OrderBook() is not supported yet');
3707
+ }
3705
3708
  parseLastPrice(price, market = undefined) {
3706
3709
  throw new NotSupported(this.id + ' parseLastPrice() is not supported yet');
3707
3710
  }
package/js/src/binance.js CHANGED
@@ -8607,7 +8607,7 @@ export default class binance extends Exchange {
8607
8607
  extendedParams = this.omit(extendedParams, ['orderidlist', 'origclientorderidlist']);
8608
8608
  query = this.rawencode(extendedParams);
8609
8609
  const orderidlistLength = orderidlist.length;
8610
- const origclientorderidlistLength = orderidlist.length;
8610
+ const origclientorderidlistLength = origclientorderidlist.length;
8611
8611
  if (orderidlistLength > 0) {
8612
8612
  query = query + '&' + 'orderidlist=[' + orderidlist.join(',') + ']';
8613
8613
  }
package/js/src/bingx.js CHANGED
@@ -2015,6 +2015,9 @@ export default class bingx extends Exchange {
2015
2015
  const positionSide = this.safeString2(order, 'positionSide', 'ps');
2016
2016
  const marketType = (positionSide === undefined) ? 'spot' : 'swap';
2017
2017
  const marketId = this.safeString2(order, 'symbol', 's');
2018
+ if (market === undefined) {
2019
+ market = this.safeMarket(marketId, undefined, undefined, marketType);
2020
+ }
2018
2021
  const symbol = this.safeSymbol(marketId, market, '-', marketType);
2019
2022
  const orderId = this.safeString2(order, 'orderId', 'i');
2020
2023
  const side = this.safeStringLower2(order, 'side', 'S');
@@ -2380,16 +2383,15 @@ export default class bingx extends Exchange {
2380
2383
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2381
2384
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2382
2385
  */
2383
- if (symbol === undefined) {
2384
- throw new ArgumentsRequired(this.id + ' fetchOrders() requires a symbol argument');
2385
- }
2386
2386
  await this.loadMarkets();
2387
- const market = this.market(symbol);
2388
- const request = {
2389
- 'symbol': market['id'],
2390
- };
2387
+ let market = undefined;
2388
+ const request = {};
2389
+ if (symbol !== undefined) {
2390
+ market = this.market(symbol);
2391
+ request['symbol'] = market['id'];
2392
+ }
2391
2393
  let response = undefined;
2392
- const [marketType, query] = this.handleMarketTypeAndParams('fetchOrder', market, params);
2394
+ const [marketType, query] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2393
2395
  if (marketType === 'spot') {
2394
2396
  response = await this.spotV1PrivateGetTradeOpenOrders(this.extend(request, query));
2395
2397
  }
package/js/src/bithumb.js CHANGED
@@ -948,11 +948,11 @@ export default class bithumb extends Exchange {
948
948
  };
949
949
  return await this.privatePostTradeCancel(this.extend(request, params));
950
950
  }
951
- cancelUnifiedOrder(order, params = {}) {
951
+ async cancelUnifiedOrder(order, params = {}) {
952
952
  const request = {
953
953
  'side': order['side'],
954
954
  };
955
- return this.cancelOrder(order['id'], order['symbol'], this.extend(request, params));
955
+ return await this.cancelOrder(order['id'], order['symbol'], this.extend(request, params));
956
956
  }
957
957
  async withdraw(code, amount, address, tag = undefined, params = {}) {
958
958
  /**
package/js/src/bitmart.js CHANGED
@@ -1337,48 +1337,58 @@ export default class bitmart extends Exchange {
1337
1337
  //
1338
1338
  // public fetchTrades spot ( amount = count * price )
1339
1339
  //
1340
- // {
1341
- // "amount": "818.94",
1342
- // "order_time": "1637601839035", // ETH/USDT
1343
- // "price": "4221.99",
1344
- // "count": "0.19397",
1345
- // "type": "buy"
1346
- // }
1340
+ // {
1341
+ // "amount": "818.94",
1342
+ // "order_time": "1637601839035", // ETH/USDT
1343
+ // "price": "4221.99",
1344
+ // "count": "0.19397",
1345
+ // "type": "buy"
1346
+ // }
1347
1347
  //
1348
1348
  // spot: fetchMyTrades
1349
1349
  //
1350
- // {
1351
- // "tradeId":"182342999769370687",
1352
- // "orderId":"183270218784142990",
1353
- // "clientOrderId":"183270218784142990",
1354
- // "symbol":"ADA_USDT",
1355
- // "side":"buy",
1356
- // "orderMode":"spot",
1357
- // "type":"market",
1358
- // "price":"0.245948",
1359
- // "size":"20.71",
1360
- // "notional":"5.09358308",
1361
- // "fee":"0.00509358",
1362
- // "feeCoinName":"USDT",
1363
- // "tradeRole":"taker",
1364
- // "createTime":1695658457836,
1365
- // }
1350
+ // {
1351
+ // "tradeId":"182342999769370687",
1352
+ // "orderId":"183270218784142990",
1353
+ // "clientOrderId":"183270218784142990",
1354
+ // "symbol":"ADA_USDT",
1355
+ // "side":"buy",
1356
+ // "orderMode":"spot",
1357
+ // "type":"market",
1358
+ // "price":"0.245948",
1359
+ // "size":"20.71",
1360
+ // "notional":"5.09358308",
1361
+ // "fee":"0.00509358",
1362
+ // "feeCoinName":"USDT",
1363
+ // "tradeRole":"taker",
1364
+ // "createTime":1695658457836,
1365
+ // }
1366
1366
  //
1367
1367
  // swap: fetchMyTrades
1368
1368
  //
1369
- // {
1370
- // "order_id": "230930336848609",
1371
- // "trade_id": "6212604014",
1372
- // "symbol": "BTCUSDT",
1373
- // "side": 3,
1374
- // "price": "26910.4",
1375
- // "vol": "1",
1376
- // "exec_type": "Taker",
1377
- // "profit": false,
1378
- // "create_time": 1695961596692,
1379
- // "realised_profit": "-0.0003",
1380
- // "paid_fees": "0.01614624"
1381
- // }
1369
+ // {
1370
+ // "order_id": "230930336848609",
1371
+ // "trade_id": "6212604014",
1372
+ // "symbol": "BTCUSDT",
1373
+ // "side": 3,
1374
+ // "price": "26910.4",
1375
+ // "vol": "1",
1376
+ // "exec_type": "Taker",
1377
+ // "profit": false,
1378
+ // "create_time": 1695961596692,
1379
+ // "realised_profit": "-0.0003",
1380
+ // "paid_fees": "0.01614624"
1381
+ // }
1382
+ //
1383
+ // ws swap
1384
+ //
1385
+ // {
1386
+ // 'fee': '-0.000044502',
1387
+ // 'feeCcy': 'USDT',
1388
+ // 'fillPrice': '74.17',
1389
+ // 'fillQty': '1',
1390
+ // 'lastTradeID': 6802340762
1391
+ // }
1382
1392
  //
1383
1393
  const timestamp = this.safeIntegerN(trade, ['order_time', 'createTime', 'create_time']);
1384
1394
  const isPublicTrade = ('order_time' in trade);
@@ -1392,7 +1402,7 @@ export default class bitmart extends Exchange {
1392
1402
  side = this.safeString(trade, 'type');
1393
1403
  }
1394
1404
  else {
1395
- amount = this.safeString2(trade, 'size', 'vol');
1405
+ amount = this.safeStringN(trade, ['size', 'vol', 'fillQty']);
1396
1406
  cost = this.safeString(trade, 'notional');
1397
1407
  type = this.safeString(trade, 'type');
1398
1408
  side = this.parseOrderSide(this.safeString(trade, 'side'));
@@ -1414,14 +1424,14 @@ export default class bitmart extends Exchange {
1414
1424
  }
1415
1425
  return this.safeTrade({
1416
1426
  'info': trade,
1417
- 'id': this.safeString2(trade, 'tradeId', 'trade_id'),
1427
+ 'id': this.safeStringN(trade, ['tradeId', 'trade_id', 'lastTradeID']),
1418
1428
  'order': this.safeString2(trade, 'orderId', 'order_id'),
1419
1429
  'timestamp': timestamp,
1420
1430
  'datetime': this.iso8601(timestamp),
1421
1431
  'symbol': market['symbol'],
1422
1432
  'type': type,
1423
1433
  'side': side,
1424
- 'price': this.safeString(trade, 'price'),
1434
+ 'price': this.safeString2(trade, 'price', 'fillPrice'),
1425
1435
  'amount': amount,
1426
1436
  'cost': cost,
1427
1437
  'takerOrMaker': this.safeStringLower2(trade, 'tradeRole', 'exec_type'),
@@ -1475,38 +1485,45 @@ export default class bitmart extends Exchange {
1475
1485
  parseOHLCV(ohlcv, market = undefined) {
1476
1486
  //
1477
1487
  // spot
1478
- //
1479
- // [
1480
- // "1699512060", // timestamp
1481
- // "36746.49", // open
1482
- // "36758.71", // high
1483
- // "36736.13", // low
1484
- // "36755.99", // close
1485
- // "2.83965", // base volume
1486
- // "104353.57" // quote volume
1487
- // ]
1488
+ // [
1489
+ // "1699512060", // timestamp
1490
+ // "36746.49", // open
1491
+ // "36758.71", // high
1492
+ // "36736.13", // low
1493
+ // "36755.99", // close
1494
+ // "2.83965", // base volume
1495
+ // "104353.57" // quote volume
1496
+ // ]
1488
1497
  //
1489
1498
  // swap
1490
- //
1491
- // {
1492
- // "low_price": "20090.3",
1493
- // "high_price": "20095.5",
1494
- // "open_price": "20092.6",
1495
- // "close_price": "20091.4",
1496
- // "volume": "8748",
1497
- // "timestamp": 1665002281
1498
- // }
1499
+ // {
1500
+ // "low_price": "20090.3",
1501
+ // "high_price": "20095.5",
1502
+ // "open_price": "20092.6",
1503
+ // "close_price": "20091.4",
1504
+ // "volume": "8748",
1505
+ // "timestamp": 1665002281
1506
+ // }
1499
1507
  //
1500
1508
  // ws
1501
- //
1502
- // [
1503
- // 1631056350, // timestamp
1504
- // "46532.83", // open
1505
- // "46555.71", // high
1506
- // "46511.41", // low
1507
- // "46555.71", // close
1508
- // "0.25", // volume
1509
- // ]
1509
+ // [
1510
+ // 1631056350, // timestamp
1511
+ // "46532.83", // open
1512
+ // "46555.71", // high
1513
+ // "46511.41", // low
1514
+ // "46555.71", // close
1515
+ // "0.25", // volume
1516
+ // ]
1517
+ //
1518
+ // ws swap
1519
+ // {
1520
+ // "symbol":"BTCUSDT",
1521
+ // "o":"146.24",
1522
+ // "h":"146.24",
1523
+ // "l":"146.24",
1524
+ // "c":"146.24",
1525
+ // "v":"146"
1526
+ // }
1510
1527
  //
1511
1528
  if (Array.isArray(ohlcv)) {
1512
1529
  return [
@@ -1520,12 +1537,12 @@ export default class bitmart extends Exchange {
1520
1537
  }
1521
1538
  else {
1522
1539
  return [
1523
- this.safeTimestamp(ohlcv, 'timestamp'),
1524
- this.safeNumber(ohlcv, 'open_price'),
1525
- this.safeNumber(ohlcv, 'high_price'),
1526
- this.safeNumber(ohlcv, 'low_price'),
1527
- this.safeNumber(ohlcv, 'close_price'),
1528
- this.safeNumber(ohlcv, 'volume'),
1540
+ this.safeTimestamp2(ohlcv, 'timestamp', 'ts'),
1541
+ this.safeNumber2(ohlcv, 'open_price', 'o'),
1542
+ this.safeNumber2(ohlcv, 'high_price', 'h'),
1543
+ this.safeNumber2(ohlcv, 'low_price', 'l'),
1544
+ this.safeNumber2(ohlcv, 'close_price', 'c'),
1545
+ this.safeNumber2(ohlcv, 'volume', 'v'),
1529
1546
  ];
1530
1547
  }
1531
1548
  }
package/js/src/bitopro.js CHANGED
@@ -1256,11 +1256,11 @@ export default class bitopro extends Exchange {
1256
1256
  //
1257
1257
  return this.parseOrders(orders, market, since, limit);
1258
1258
  }
1259
- fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1259
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1260
1260
  const request = {
1261
1261
  'statusKind': 'OPEN',
1262
1262
  };
1263
- return this.fetchOrders(symbol, since, limit, this.extend(request, params));
1263
+ return await this.fetchOrders(symbol, since, limit, this.extend(request, params));
1264
1264
  }
1265
1265
  async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1266
1266
  /**
package/js/src/bybit.js CHANGED
@@ -5745,9 +5745,11 @@ export default class bybit extends Exchange {
5745
5745
  else if (symbolsLength === 1) {
5746
5746
  symbol = symbols[0];
5747
5747
  }
5748
+ symbols = this.marketSymbols(symbols);
5748
5749
  }
5749
5750
  else if (symbols !== undefined) {
5750
5751
  symbol = symbols;
5752
+ symbols = [this.symbol(symbol)];
5751
5753
  }
5752
5754
  await this.loadMarkets();
5753
5755
  const [enableUnifiedMargin, enableUnifiedAccount] = await this.isUnifiedEnabled();
@@ -5757,14 +5759,12 @@ export default class bybit extends Exchange {
5757
5759
  let isUsdcSettled = false;
5758
5760
  if (symbol !== undefined) {
5759
5761
  market = this.market(symbol);
5762
+ symbol = market['symbol'];
5760
5763
  request['symbol'] = market['id'];
5761
5764
  isUsdcSettled = market['settle'] === 'USDC';
5762
5765
  }
5763
5766
  let type = undefined;
5764
5767
  [type, params] = this.getBybitType('fetchPositions', market, params);
5765
- if (type === 'spot') {
5766
- throw new NotSupported(this.id + ' fetchPositions() not support spot market');
5767
- }
5768
5768
  if (type === 'linear' || type === 'inverse') {
5769
5769
  const baseCoin = this.safeString(params, 'baseCoin');
5770
5770
  if (type === 'linear') {
package/js/src/coinex.js CHANGED
@@ -33,6 +33,7 @@ export default class coinex extends Exchange {
33
33
  // 20 per 2 seconds => 10 per second => weight = 40
34
34
  'rateLimit': 2.5,
35
35
  'pro': true,
36
+ 'certified': true,
36
37
  'has': {
37
38
  'CORS': undefined,
38
39
  'spot': true,
package/js/src/coinsph.js CHANGED
@@ -38,6 +38,9 @@ export default class coinsph extends Exchange {
38
38
  'closeAllPositions': false,
39
39
  'closePosition': false,
40
40
  'createDepositAddress': false,
41
+ 'createMarketBuyOrderWithCost': true,
42
+ 'createMarketOrderWithCost': false,
43
+ 'createMarketSellOrderWithCost': false,
41
44
  'createOrder': true,
42
45
  'createPostOnlyOrder': false,
43
46
  'createReduceOnlyOrder': false,
@@ -1065,12 +1068,14 @@ export default class coinsph extends Exchange {
1065
1068
  * @method
1066
1069
  * @name coinsph#createOrder
1067
1070
  * @description create a trade order
1071
+ * @see https://coins-docs.github.io/rest-api/#new-order--trade
1068
1072
  * @param {string} symbol unified symbol of the market to create an order in
1069
1073
  * @param {string} type 'market', 'limit', 'stop_loss', 'take_profit', 'stop_loss_limit', 'take_profit_limit' or 'limit_maker'
1070
1074
  * @param {string} side 'buy' or 'sell'
1071
1075
  * @param {float} amount how much of currency you want to trade in units of base currency
1072
1076
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1073
1077
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1078
+ * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount for market buy orders
1074
1079
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1075
1080
  */
1076
1081
  // todo: add test order low priority
@@ -1106,24 +1111,29 @@ export default class coinsph extends Exchange {
1106
1111
  request['quantity'] = this.amountToPrecision(symbol, amount);
1107
1112
  }
1108
1113
  else if (orderSide === 'BUY') {
1109
- const quoteOrderQty = this.safeNumber2(params, 'cost', 'quoteOrderQty');
1110
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
1111
- if (quoteOrderQty !== undefined) {
1112
- amount = quoteOrderQty;
1114
+ let quoteAmount = undefined;
1115
+ let createMarketBuyOrderRequiresPrice = true;
1116
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1117
+ const cost = this.safeNumber2(params, 'cost', 'quoteOrderQty');
1118
+ params = this.omit(params, 'cost');
1119
+ if (cost !== undefined) {
1120
+ quoteAmount = this.costToPrecision(symbol, cost);
1113
1121
  }
1114
1122
  else if (createMarketBuyOrderRequiresPrice) {
1115
1123
  if (price === undefined) {
1116
- 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 to supply the cost in the amount argument (the exchange-specific behaviour)");
1124
+ 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');
1117
1125
  }
1118
1126
  else {
1119
1127
  const amountString = this.numberToString(amount);
1120
1128
  const priceString = this.numberToString(price);
1121
- const quoteAmount = Precise.stringMul(amountString, priceString);
1122
- amount = this.parseNumber(quoteAmount);
1129
+ const costRequest = Precise.stringMul(amountString, priceString);
1130
+ quoteAmount = this.costToPrecision(symbol, costRequest);
1123
1131
  }
1124
1132
  }
1125
- request['quoteOrderQty'] = this.costToPrecision(symbol, amount);
1126
- params = this.omit(params, 'cost', 'quoteOrderQty');
1133
+ else {
1134
+ quoteAmount = this.costToPrecision(symbol, amount);
1135
+ }
1136
+ request['quoteOrderQty'] = quoteAmount;
1127
1137
  }
1128
1138
  }
1129
1139
  if (orderType === 'STOP_LOSS' || orderType === 'STOP_LOSS_LIMIT' || orderType === 'TAKE_PROFIT' || orderType === 'TAKE_PROFIT_LIMIT') {
package/js/src/htx.d.ts CHANGED
@@ -83,6 +83,7 @@ export default class htx extends Exchange {
83
83
  fetchOpenOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
84
84
  parseOrderStatus(status: any): string;
85
85
  parseOrder(order: any, market?: Market): Order;
86
+ createMarketBuyOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
86
87
  createSpotOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<any>;
87
88
  createContractOrderRequest(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): any;
88
89
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
package/js/src/htx.js CHANGED
@@ -41,6 +41,9 @@ export default class htx extends Exchange {
41
41
  'cancelOrder': true,
42
42
  'cancelOrders': true,
43
43
  'createDepositAddress': undefined,
44
+ 'createMarketBuyOrderWithCost': true,
45
+ 'createMarketOrderWithCost': false,
46
+ 'createMarketSellOrderWithCost': false,
44
47
  'createOrder': true,
45
48
  'createOrders': true,
46
49
  'createReduceOnlyOrder': false,
@@ -4843,6 +4846,25 @@ export default class htx extends Exchange {
4843
4846
  'trades': trades,
4844
4847
  }, market);
4845
4848
  }
4849
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
4850
+ /**
4851
+ * @method
4852
+ * @name htx#createMarketBuyOrderWithCost
4853
+ * @description create a market buy order by providing the symbol and cost
4854
+ * @see https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
4855
+ * @param {string} symbol unified symbol of the market to create an order in
4856
+ * @param {float} cost how much you want to trade in units of the quote currency
4857
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4858
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
4859
+ */
4860
+ await this.loadMarkets();
4861
+ const market = this.market(symbol);
4862
+ if (!market['spot']) {
4863
+ throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
4864
+ }
4865
+ params['createMarketBuyOrderRequiresPrice'] = false;
4866
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
4867
+ }
4846
4868
  async createSpotOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
4847
4869
  /**
4848
4870
  * @method
@@ -4856,6 +4878,7 @@ export default class htx extends Exchange {
4856
4878
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4857
4879
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4858
4880
  * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
4881
+ * @param {float} [params.cost] the quote quantity that can be used as an alternative for the amount for market buy orders
4859
4882
  * @returns {object} request to be sent to the exchange
4860
4883
  */
4861
4884
  await this.loadMarkets();
@@ -4930,9 +4953,17 @@ export default class htx extends Exchange {
4930
4953
  request['source'] = 'c2c-margin-api';
4931
4954
  }
4932
4955
  if ((orderType === 'market') && (side === 'buy')) {
4933
- if (this.options['createMarketBuyOrderRequiresPrice']) {
4956
+ let quoteAmount = undefined;
4957
+ let createMarketBuyOrderRequiresPrice = true;
4958
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
4959
+ const cost = this.safeNumber(params, 'cost');
4960
+ params = this.omit(params, 'cost');
4961
+ if (cost !== undefined) {
4962
+ quoteAmount = this.amountToPrecision(symbol, cost);
4963
+ }
4964
+ else if (createMarketBuyOrderRequiresPrice) {
4934
4965
  if (price === undefined) {
4935
- throw new InvalidOrder(this.id + " market buy order requires price argument to calculate cost (total amount of quote currency to spend for buying, amount * price). To switch off this warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = false. Make sure you know what you're doing.");
4966
+ 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');
4936
4967
  }
4937
4968
  else {
4938
4969
  // despite that cost = amount * price is in quote currency and should have quote precision
@@ -4943,12 +4974,13 @@ export default class htx extends Exchange {
4943
4974
  // we use amountToPrecision here because the exchange requires cost in base precision
4944
4975
  const amountString = this.numberToString(amount);
4945
4976
  const priceString = this.numberToString(price);
4946
- request['amount'] = this.costToPrecision(symbol, Precise.stringMul(amountString, priceString));
4977
+ quoteAmount = this.amountToPrecision(symbol, Precise.stringMul(amountString, priceString));
4947
4978
  }
4948
4979
  }
4949
4980
  else {
4950
- request['amount'] = this.costToPrecision(symbol, amount);
4981
+ quoteAmount = this.amountToPrecision(symbol, amount);
4951
4982
  }
4983
+ request['amount'] = quoteAmount;
4952
4984
  }
4953
4985
  else {
4954
4986
  request['amount'] = this.amountToPrecision(symbol, amount);
@@ -5080,6 +5112,7 @@ export default class htx extends Exchange {
5080
5112
  * @param {bool} [params.postOnly] *contract only* true or false
5081
5113
  * @param {int} [params.leverRate] *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
5082
5114
  * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
5115
+ * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
5083
5116
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5084
5117
  */
5085
5118
  await this.loadMarkets();
@@ -51,6 +51,7 @@ export default class huobijp extends Exchange {
51
51
  fetchOpenOrdersV2(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
52
52
  parseOrderStatus(status: any): string;
53
53
  parseOrder(order: any, market?: Market): Order;
54
+ createMarketBuyOrderWithCost(symbol: string, cost: any, params?: {}): Promise<Order>;
54
55
  createOrder(symbol: string, type: OrderType, side: OrderSide, amount: any, price?: any, params?: {}): Promise<Order>;
55
56
  cancelOrder(id: string, symbol?: Str, params?: {}): Promise<any>;
56
57
  cancelOrders(ids: any, symbol?: Str, params?: {}): Promise<any>;
package/js/src/huobijp.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/huobijp.js';
9
- import { AuthenticationError, ExchangeError, PermissionDenied, ExchangeNotAvailable, OnMaintenance, InvalidOrder, OrderNotFound, InsufficientFunds, BadSymbol, BadRequest, RequestTimeout, NetworkError, ArgumentsRequired } from './base/errors.js';
9
+ import { AuthenticationError, ExchangeError, PermissionDenied, ExchangeNotAvailable, OnMaintenance, InvalidOrder, OrderNotFound, InsufficientFunds, BadSymbol, BadRequest, RequestTimeout, NetworkError, ArgumentsRequired, NotSupported } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { TRUNCATE, TICK_SIZE } from './base/functions/number.js';
12
12
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
@@ -37,6 +37,9 @@ export default class huobijp extends Exchange {
37
37
  'cancelAllOrders': true,
38
38
  'cancelOrder': true,
39
39
  'cancelOrders': true,
40
+ 'createMarketBuyOrderWithCost': true,
41
+ 'createMarketOrderWithCost': false,
42
+ 'createMarketSellOrderWithCost': false,
40
43
  'createOrder': true,
41
44
  'createStopLimitOrder': false,
42
45
  'createStopMarketOrder': false,
@@ -1361,6 +1364,24 @@ export default class huobijp extends Exchange {
1361
1364
  'trades': undefined,
1362
1365
  }, market);
1363
1366
  }
1367
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1368
+ /**
1369
+ * @method
1370
+ * @name huobijp#createMarketBuyOrderWithCost
1371
+ * @description create a market buy order by providing the symbol and cost
1372
+ * @param {string} symbol unified symbol of the market to create an order in
1373
+ * @param {float} cost how much you want to trade in units of the quote currency
1374
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1375
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1376
+ */
1377
+ await this.loadMarkets();
1378
+ const market = this.market(symbol);
1379
+ if (!market['spot']) {
1380
+ throw new NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
1381
+ }
1382
+ params['createMarketBuyOrderRequiresPrice'] = false;
1383
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1384
+ }
1364
1385
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1365
1386
  /**
1366
1387
  * @method
@@ -1393,9 +1414,17 @@ export default class huobijp extends Exchange {
1393
1414
  }
1394
1415
  params = this.omit(params, ['clientOrderId', 'client-order-id']);
1395
1416
  if ((type === 'market') && (side === 'buy')) {
1396
- if (this.options['createMarketBuyOrderRequiresPrice']) {
1417
+ let quoteAmount = undefined;
1418
+ let createMarketBuyOrderRequiresPrice = true;
1419
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1420
+ const cost = this.safeNumber(params, 'cost');
1421
+ params = this.omit(params, 'cost');
1422
+ if (cost !== undefined) {
1423
+ quoteAmount = this.amountToPrecision(symbol, cost);
1424
+ }
1425
+ else if (createMarketBuyOrderRequiresPrice) {
1397
1426
  if (price === undefined) {
1398
- throw new InvalidOrder(this.id + " market buy order requires price argument to calculate cost (total amount of quote currency to spend for buying, amount * price). To switch off this warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = false. Make sure you know what you're doing.");
1427
+ 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');
1399
1428
  }
1400
1429
  else {
1401
1430
  // despite that cost = amount * price is in quote currency and should have quote precision
@@ -1406,13 +1435,13 @@ export default class huobijp extends Exchange {
1406
1435
  // we use amountToPrecision here because the exchange requires cost in base precision
1407
1436
  const amountString = this.numberToString(amount);
1408
1437
  const priceString = this.numberToString(price);
1409
- const baseAmount = Precise.stringMul(amountString, priceString);
1410
- request['amount'] = this.costToPrecision(symbol, baseAmount);
1438
+ quoteAmount = this.amountToPrecision(symbol, Precise.stringMul(amountString, priceString));
1411
1439
  }
1412
1440
  }
1413
1441
  else {
1414
- request['amount'] = this.costToPrecision(symbol, amount);
1442
+ quoteAmount = this.amountToPrecision(symbol, amount);
1415
1443
  }
1444
+ request['amount'] = quoteAmount;
1416
1445
  }
1417
1446
  else {
1418
1447
  request['amount'] = this.amountToPrecision(symbol, amount);