ccxt 4.3.11 → 4.3.13

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.
Files changed (82) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/ccxt.js +1 -1
  3. package/dist/cjs/src/base/Exchange.js +15 -0
  4. package/dist/cjs/src/bigone.js +22 -22
  5. package/dist/cjs/src/binance.js +5 -5
  6. package/dist/cjs/src/bingx.js +2 -2
  7. package/dist/cjs/src/bitget.js +7 -4
  8. package/dist/cjs/src/bitmart.js +3 -8
  9. package/dist/cjs/src/bitmex.js +2 -2
  10. package/dist/cjs/src/bybit.js +82 -71
  11. package/dist/cjs/src/coinbase.js +8 -8
  12. package/dist/cjs/src/coinbaseinternational.js +2 -2
  13. package/dist/cjs/src/coinex.js +513 -449
  14. package/dist/cjs/src/coinlist.js +12 -12
  15. package/dist/cjs/src/coinmetro.js +2 -2
  16. package/dist/cjs/src/cryptocom.js +16 -16
  17. package/dist/cjs/src/gate.js +2 -2
  18. package/dist/cjs/src/hitbtc.js +3 -3
  19. package/dist/cjs/src/htx.js +3 -7
  20. package/dist/cjs/src/indodax.js +2 -2
  21. package/dist/cjs/src/kraken.js +3 -1
  22. package/dist/cjs/src/kucoin.js +4 -4
  23. package/dist/cjs/src/kucoinfutures.js +6 -6
  24. package/dist/cjs/src/mexc.js +5 -5
  25. package/dist/cjs/src/okx.js +6 -6
  26. package/dist/cjs/src/poloniexfutures.js +4 -4
  27. package/dist/cjs/src/pro/bitget.js +140 -89
  28. package/dist/cjs/src/pro/bybit.js +196 -11
  29. package/dist/cjs/src/pro/coinbase.js +107 -29
  30. package/dist/cjs/src/pro/mexc.js +21 -1
  31. package/dist/cjs/src/probit.js +2 -2
  32. package/dist/cjs/src/whitebit.js +76 -1
  33. package/dist/cjs/src/woo.js +2 -2
  34. package/js/ccxt.d.ts +1 -1
  35. package/js/ccxt.js +1 -1
  36. package/js/src/abstract/bybit.d.ts +1 -0
  37. package/js/src/base/Exchange.d.ts +10 -6
  38. package/js/src/base/Exchange.js +15 -0
  39. package/js/src/base/types.d.ts +17 -2
  40. package/js/src/bigone.js +22 -22
  41. package/js/src/binance.d.ts +2 -9
  42. package/js/src/binance.js +5 -5
  43. package/js/src/bingx.js +2 -2
  44. package/js/src/bitget.d.ts +4 -31
  45. package/js/src/bitget.js +7 -4
  46. package/js/src/bitmart.d.ts +4 -24
  47. package/js/src/bitmart.js +3 -8
  48. package/js/src/bitmex.js +2 -2
  49. package/js/src/bybit.d.ts +7 -9
  50. package/js/src/bybit.js +82 -71
  51. package/js/src/coinbase.js +8 -8
  52. package/js/src/coinbaseinternational.js +2 -2
  53. package/js/src/coinex.d.ts +4 -24
  54. package/js/src/coinex.js +513 -449
  55. package/js/src/coinlist.js +12 -12
  56. package/js/src/coinmetro.js +2 -2
  57. package/js/src/cryptocom.js +16 -16
  58. package/js/src/digifinex.d.ts +3 -10
  59. package/js/src/gate.js +2 -2
  60. package/js/src/hitbtc.js +3 -3
  61. package/js/src/htx.d.ts +3 -13
  62. package/js/src/htx.js +3 -7
  63. package/js/src/indodax.js +2 -2
  64. package/js/src/kraken.js +3 -1
  65. package/js/src/kucoin.js +4 -4
  66. package/js/src/kucoinfutures.js +6 -6
  67. package/js/src/mexc.js +5 -5
  68. package/js/src/okx.d.ts +3 -10
  69. package/js/src/okx.js +6 -6
  70. package/js/src/poloniexfutures.js +4 -4
  71. package/js/src/pro/bitget.js +140 -89
  72. package/js/src/pro/bybit.d.ts +5 -1
  73. package/js/src/pro/bybit.js +196 -11
  74. package/js/src/pro/coinbase.d.ts +4 -0
  75. package/js/src/pro/coinbase.js +107 -29
  76. package/js/src/pro/mexc.js +21 -1
  77. package/js/src/probit.js +2 -2
  78. package/js/src/whitebit.d.ts +1 -0
  79. package/js/src/whitebit.js +76 -1
  80. package/js/src/woo.js +2 -2
  81. package/package.json +6 -5
  82. package/dist/cjs/src/flowbtc.js +0 -35
@@ -694,55 +694,70 @@ export default class bitget extends bitgetRest {
694
694
  // "side": "buy",
695
695
  // "tradeId": "1116461060594286593"
696
696
  // }
697
+ // swap private
697
698
  //
698
- // order with trade in it
699
- // {
700
- // accBaseVolume: '0.1',
701
- // baseVolume: '0.1',
702
- // cTime: '1709221342922',
703
- // clientOid: '1147122943507734528',
704
- // enterPointSource: 'API',
705
- // feeDetail: [Array],
706
- // fillFee: '-0.0049578',
707
- // fillFeeCoin: 'USDT',
708
- // fillNotionalUsd: '8.263',
709
- // fillPrice: '82.63',
710
- // fillTime: '1709221342986',
711
- // force: 'gtc',
712
- // instId: 'LTCUSDT',
713
- // leverage: '10',
714
- // marginCoin: 'USDT',
715
- // marginMode: 'crossed',
716
- // notionalUsd: '8.268',
717
- // orderId: '1147122943499345921',
718
- // orderType: 'market',
719
- // pnl: '0',
720
- // posMode: 'hedge_mode',
721
- // posSide: 'short',
722
- // price: '0',
723
- // priceAvg: '82.63',
724
- // reduceOnly: 'no',
725
- // side: 'sell',
726
- // size: '0.1',
727
- // status: 'filled',
728
- // tradeId: '1147122943772479563',
729
- // tradeScope: 'T',
730
- // tradeSide: 'open',
731
- // uTime: '1709221342986'
732
- // }
699
+ // {
700
+ // "orderId": "1169142761031114781",
701
+ // "tradeId": "1169142761312637004",
702
+ // "symbol": "LTCUSDT",
703
+ // "orderType": "market",
704
+ // "side": "buy",
705
+ // "price": "80.87",
706
+ // "baseVolume": "0.1",
707
+ // "quoteVolume": "8.087",
708
+ // "profit": "0",
709
+ // "tradeSide": "open",
710
+ // "posMode": "hedge_mode",
711
+ // "tradeScope": "taker",
712
+ // "feeDetail": [
713
+ // {
714
+ // "feeCoin": "USDT",
715
+ // "deduction": "no",
716
+ // "totalDeductionFee": "0",
717
+ // "totalFee": "-0.0048522"
718
+ // }
719
+ // ],
720
+ // "cTime": "1714471276596",
721
+ // "uTime": "1714471276596"
722
+ // }
723
+ // spot private
724
+ // {
725
+ // "orderId": "1169142457356959747",
726
+ // "tradeId": "1169142457636958209",
727
+ // "symbol": "LTCUSDT",
728
+ // "orderType": "market",
729
+ // "side": "buy",
730
+ // "priceAvg": "81.069",
731
+ // "size": "0.074",
732
+ // "amount": "5.999106",
733
+ // "tradeScope": "taker",
734
+ // "feeDetail": [
735
+ // {
736
+ // "feeCoin": "LTC",
737
+ // "deduction": "no",
738
+ // "totalDeductionFee": "0",
739
+ // "totalFee": "0.000074"
740
+ // }
741
+ // ],
742
+ // "cTime": "1714471204194",
743
+ // "uTime": "1714471204194"
744
+ // }
733
745
  //
734
- const instId = this.safeString(trade, 'instId');
746
+ const instId = this.safeString2(trade, 'symbol', 'instId');
747
+ const posMode = this.safeString(trade, 'posMode');
748
+ const defaultType = (posMode !== undefined) ? 'contract' : 'spot';
735
749
  if (market === undefined) {
736
- market = this.safeMarket(instId, undefined, undefined, 'contract');
750
+ market = this.safeMarket(instId, undefined, undefined, defaultType);
737
751
  }
738
752
  const timestamp = this.safeIntegerN(trade, ['uTime', 'cTime', 'ts']);
739
- const feeCost = this.safeString(trade, 'fillFee');
753
+ const feeDetail = this.safeList(trade, 'feeDetail', []);
754
+ const first = this.safeDict(feeDetail, 0);
740
755
  let fee = undefined;
741
- if (feeCost !== undefined) {
742
- const feeCurrencyId = this.safeString(trade, 'fillFeeCoin');
756
+ if (first !== undefined) {
757
+ const feeCurrencyId = this.safeString(first, 'feeCoin');
743
758
  const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId);
744
759
  fee = {
745
- 'cost': Precise.stringAbs(feeCost),
760
+ 'cost': Precise.stringAbs(this.safeString(first, 'totalFee')),
746
761
  'currency': feeCurrencyCode,
747
762
  };
748
763
  }
@@ -753,12 +768,12 @@ export default class bitget extends bitgetRest {
753
768
  'timestamp': timestamp,
754
769
  'datetime': this.iso8601(timestamp),
755
770
  'symbol': market['symbol'],
756
- 'type': undefined,
771
+ 'type': this.safeString(trade, 'orderType'),
757
772
  'side': this.safeString(trade, 'side'),
758
- 'takerOrMaker': undefined,
773
+ 'takerOrMaker': this.safeString(trade, 'tradeScope'),
759
774
  'price': this.safeString2(trade, 'priceAvg', 'price'),
760
- 'amount': this.safeString(trade, 'size'),
761
- 'cost': this.safeString(trade, 'fillNotionalUsd'),
775
+ 'amount': this.safeString2(trade, 'size', 'baseVolume'),
776
+ 'cost': this.safeString2(trade, 'amount', 'quoteVolume'),
762
777
  'fee': fee,
763
778
  }, market);
764
779
  }
@@ -1164,9 +1179,6 @@ export default class bitget extends bitgetRest {
1164
1179
  const marketSymbols = {};
1165
1180
  for (let i = 0; i < data.length; i++) {
1166
1181
  const order = data[i];
1167
- if ('tradeId' in order) {
1168
- this.handleMyTrades(client, order);
1169
- }
1170
1182
  const marketId = this.safeString(order, 'instId');
1171
1183
  const market = this.safeMarket(marketId, undefined, undefined, marketType);
1172
1184
  const parsed = this.parseWsOrder(order, market);
@@ -1366,8 +1378,6 @@ export default class bitget extends bitgetRest {
1366
1378
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1367
1379
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1368
1380
  */
1369
- // only contracts stream provides the trade info consistently in between order updates
1370
- // the spot stream only provides on limit orders updates so we can't support it for spot
1371
1381
  await this.loadMarkets();
1372
1382
  let market = undefined;
1373
1383
  let messageHash = 'myTrades';
@@ -1376,17 +1386,12 @@ export default class bitget extends bitgetRest {
1376
1386
  symbol = market['symbol'];
1377
1387
  messageHash = messageHash + ':' + symbol;
1378
1388
  }
1379
- let type = undefined;
1380
- [type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
1381
- if (type === 'spot') {
1382
- throw new NotSupported(this.id + ' watchMyTrades is not supported for ' + type + ' markets.');
1383
- }
1384
1389
  let instType = undefined;
1385
1390
  [instType, params] = this.getInstType(market, params);
1386
- const subscriptionHash = 'order:trades';
1391
+ const subscriptionHash = 'fill:' + instType;
1387
1392
  const args = {
1388
1393
  'instType': instType,
1389
- 'channel': 'orders',
1394
+ 'channel': 'fill',
1390
1395
  'instId': 'default',
1391
1396
  };
1392
1397
  const trades = await this.watchPrivate(messageHash, subscriptionHash, args, params);
@@ -1397,34 +1402,74 @@ export default class bitget extends bitgetRest {
1397
1402
  }
1398
1403
  handleMyTrades(client, message) {
1399
1404
  //
1400
- // order and trade mixin (contract)
1401
- //
1405
+ // spot
1406
+ // {
1407
+ // "action": "snapshot",
1408
+ // "arg": {
1409
+ // "instType": "SPOT",
1410
+ // "channel": "fill",
1411
+ // "instId": "default"
1412
+ // },
1413
+ // "data": [
1414
+ // {
1415
+ // "orderId": "1169142457356959747",
1416
+ // "tradeId": "1169142457636958209",
1417
+ // "symbol": "LTCUSDT",
1418
+ // "orderType": "market",
1419
+ // "side": "buy",
1420
+ // "priceAvg": "81.069",
1421
+ // "size": "0.074",
1422
+ // "amount": "5.999106",
1423
+ // "tradeScope": "taker",
1424
+ // "feeDetail": [
1425
+ // {
1426
+ // "feeCoin": "LTC",
1427
+ // "deduction": "no",
1428
+ // "totalDeductionFee": "0",
1429
+ // "totalFee": "0.000074"
1430
+ // }
1431
+ // ],
1432
+ // "cTime": "1714471204194",
1433
+ // "uTime": "1714471204194"
1434
+ // }
1435
+ // ],
1436
+ // "ts": 1714471204270
1437
+ // }
1438
+ // swap
1402
1439
  // {
1403
- // "accBaseVolume": "0",
1404
- // "cTime": "1701920553759",
1405
- // "clientOid": "1116501214318198793",
1406
- // "enterPointSource": "WEB",
1407
- // "feeDetail": [{
1408
- // "feeCoin": "USDT",
1409
- // "fee": "-0.162003"
1410
- // }],
1411
- // "force": "gtc",
1412
- // "instId": "BTCUSDT",
1413
- // "leverage": "20",
1414
- // "marginCoin": "USDT",
1415
- // "marginMode": "isolated",
1416
- // "notionalUsd": "105",
1417
- // "orderId": "1116501214293032964",
1418
- // "orderType": "limit",
1419
- // "posMode": "hedge_mode",
1420
- // "posSide": "long",
1421
- // "price": "35000",
1422
- // "reduceOnly": "no",
1423
- // "side": "buy",
1424
- // "size": "0.003",
1425
- // "status": "canceled",
1426
- // "tradeSide": "open",
1427
- // "uTime": "1701920595866"
1440
+ // "action": "snapshot",
1441
+ // "arg": {
1442
+ // "instType": "USDT-FUTURES",
1443
+ // "channel": "fill",
1444
+ // "instId": "default"
1445
+ // },
1446
+ // "data": [
1447
+ // {
1448
+ // "orderId": "1169142761031114781",
1449
+ // "tradeId": "1169142761312637004",
1450
+ // "symbol": "LTCUSDT",
1451
+ // "orderType": "market",
1452
+ // "side": "buy",
1453
+ // "price": "80.87",
1454
+ // "baseVolume": "0.1",
1455
+ // "quoteVolume": "8.087",
1456
+ // "profit": "0",
1457
+ // "tradeSide": "open",
1458
+ // "posMode": "hedge_mode",
1459
+ // "tradeScope": "taker",
1460
+ // "feeDetail": [
1461
+ // {
1462
+ // "feeCoin": "USDT",
1463
+ // "deduction": "no",
1464
+ // "totalDeductionFee": "0",
1465
+ // "totalFee": "-0.0048522"
1466
+ // }
1467
+ // ],
1468
+ // "cTime": "1714471276596",
1469
+ // "uTime": "1714471276596"
1470
+ // }
1471
+ // ],
1472
+ // "ts": 1714471276629
1428
1473
  // }
1429
1474
  //
1430
1475
  if (this.myTrades === undefined) {
@@ -1432,13 +1477,18 @@ export default class bitget extends bitgetRest {
1432
1477
  this.myTrades = new ArrayCache(limit);
1433
1478
  }
1434
1479
  const stored = this.myTrades;
1435
- const parsed = this.parseWsTrade(message);
1436
- stored.append(parsed);
1437
- const symbol = parsed['symbol'];
1480
+ const data = this.safeList(message, 'data', []);
1481
+ const length = data.length;
1438
1482
  const messageHash = 'myTrades';
1483
+ for (let i = 0; i < length; i++) {
1484
+ const trade = data[i];
1485
+ const parsed = this.parseWsTrade(trade);
1486
+ stored.append(parsed);
1487
+ const symbol = parsed['symbol'];
1488
+ const symbolSpecificMessageHash = 'myTrades:' + symbol;
1489
+ client.resolve(stored, symbolSpecificMessageHash);
1490
+ }
1439
1491
  client.resolve(stored, messageHash);
1440
- const symbolSpecificMessageHash = 'myTrades:' + symbol;
1441
- client.resolve(stored, symbolSpecificMessageHash);
1442
1492
  }
1443
1493
  async watchBalance(params = {}) {
1444
1494
  /**
@@ -1721,6 +1771,7 @@ export default class bitget extends bitgetRest {
1721
1771
  const methods = {
1722
1772
  'ticker': this.handleTicker,
1723
1773
  'trade': this.handleTrades,
1774
+ 'fill': this.handleMyTrades,
1724
1775
  'orders': this.handleOrder,
1725
1776
  'ordersAlgo': this.handleOrder,
1726
1777
  'account': this.handleBalance,
@@ -1,11 +1,14 @@
1
1
  import bybitRest from '../bybit.js';
2
- import type { Int, OHLCV, Str, Strings, Ticker, OrderBook, Order, Trade, Tickers, Position, Balances } from '../base/types.js';
2
+ import type { Int, OHLCV, Str, Strings, Ticker, OrderBook, Order, Trade, Tickers, Position, Balances, OrderType, OrderSide, Num } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class bybit extends bybitRest {
5
5
  describe(): any;
6
6
  requestId(): any;
7
7
  getUrlByMarketType(symbol?: Str, isPrivate?: boolean, method?: Str, params?: {}): any;
8
8
  cleanParams(params: any): any;
9
+ createOrderWs(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
10
+ editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
11
+ cancelOrderWs(id: string, symbol?: Str, params?: {}): Promise<Order>;
9
12
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
10
13
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
11
14
  handleTicker(client: Client, message: any): void;
@@ -29,6 +32,7 @@ export default class bybit extends bybitRest {
29
32
  loadPositionsSnapshot(client: any, messageHash: any): Promise<void>;
30
33
  handlePositions(client: any, message: any): void;
31
34
  watchOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
35
+ handleOrderWs(client: Client, message: any): void;
32
36
  handleOrder(client: Client, message: any): void;
33
37
  parseWsSpotOrder(order: any, market?: any): Order;
34
38
  watchBalance(params?: {}): Promise<Balances>;
@@ -53,6 +53,7 @@ export default class bybit extends bybitRest {
53
53
  },
54
54
  'contract': 'wss://stream.{hostname}/v5/private',
55
55
  'usdc': 'wss://stream.{hostname}/trade/option/usdc/private/v1',
56
+ 'trade': 'wss://stream-testnet.bybit.com/v5/trade',
56
57
  },
57
58
  },
58
59
  },
@@ -71,6 +72,7 @@ export default class bybit extends bybitRest {
71
72
  },
72
73
  'contract': 'wss://stream-testnet.{hostname}/v5/private',
73
74
  'usdc': 'wss://stream-testnet.{hostname}/trade/option/usdc/private/v1',
75
+ 'trade': 'wss://stream-testnet.bybit.com/v5/trade',
74
76
  },
75
77
  },
76
78
  },
@@ -172,6 +174,133 @@ export default class bybit extends bybitRest {
172
174
  params = this.omit(params, ['type', 'subType', 'settle', 'defaultSettle', 'unifiedMargin']);
173
175
  return params;
174
176
  }
177
+ async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
178
+ /**
179
+ * @method
180
+ * @name bybit#createOrderWs
181
+ * @description create a trade order
182
+ * @see https://bybit-exchange.github.io/docs/v5/order/create-order
183
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
184
+ * @param {string} symbol unified symbol of the market to create an order in
185
+ * @param {string} type 'market' or 'limit'
186
+ * @param {string} side 'buy' or 'sell'
187
+ * @param {float} amount how much of currency you want to trade in units of base currency
188
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
189
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
190
+ * @param {string} [params.timeInForce] "GTC", "IOC", "FOK"
191
+ * @param {bool} [params.postOnly] true or false whether the order is post-only
192
+ * @param {bool} [params.reduceOnly] true or false whether the order is reduce-only
193
+ * @param {string} [params.positionIdx] *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
194
+ * @param {boolean} [params.isLeverage] *unified spot only* false then spot trading true then margin trading
195
+ * @param {string} [params.tpslMode] *contract only* 'full' or 'partial'
196
+ * @param {string} [params.mmp] *option only* market maker protection
197
+ * @param {string} [params.triggerDirection] *contract only* the direction for trigger orders, 'above' or 'below'
198
+ * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
199
+ * @param {float} [params.stopLossPrice] The price at which a stop loss order is triggered at
200
+ * @param {float} [params.takeProfitPrice] The price at which a take profit order is triggered at
201
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
202
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
203
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
204
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
205
+ * @param {string} [params.trailingAmount] the quote amount to trail away from the current market price
206
+ * @param {string} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
207
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
208
+ */
209
+ await this.loadMarkets();
210
+ const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params, true);
211
+ const url = this.urls['api']['ws']['private']['trade'];
212
+ await this.authenticate(url);
213
+ const requestId = this.requestId().toString();
214
+ const request = {
215
+ 'op': 'order.create',
216
+ 'reqId': requestId,
217
+ 'args': [
218
+ orderRequest,
219
+ ],
220
+ 'header': {
221
+ 'X-BAPI-TIMESTAMP': this.milliseconds().toString(),
222
+ 'X-BAPI-RECV-WINDOW': this.options['recvWindow'].toString(),
223
+ },
224
+ };
225
+ return await this.watch(url, requestId, request, requestId, true);
226
+ }
227
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
228
+ /**
229
+ * @method
230
+ * @name bybit#editOrderWs
231
+ * @description edit a trade order
232
+ * @see https://bybit-exchange.github.io/docs/v5/order/amend-order
233
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
234
+ * @param {string} id cancel order id
235
+ * @param {string} symbol unified symbol of the market to create an order in
236
+ * @param {string} type 'market' or 'limit'
237
+ * @param {string} side 'buy' or 'sell'
238
+ * @param {float} amount how much of currency you want to trade in units of base currency
239
+ * @param {float} price the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
240
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
241
+ * @param {float} [params.triggerPrice] The price that a trigger order is triggered at
242
+ * @param {float} [params.stopLossPrice] The price that a stop loss order is triggered at
243
+ * @param {float} [params.takeProfitPrice] The price that a take profit order is triggered at
244
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered
245
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
246
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered
247
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
248
+ * @param {string} [params.triggerBy] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for triggerPrice
249
+ * @param {string} [params.slTriggerBy] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for stopLoss
250
+ * @param {string} [params.tpTriggerby] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for takeProfit
251
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
252
+ */
253
+ await this.loadMarkets();
254
+ const orderRequest = this.editOrderRequest(id, symbol, type, side, amount, price, params);
255
+ const url = this.urls['api']['ws']['private']['trade'];
256
+ await this.authenticate(url);
257
+ const requestId = this.requestId().toString();
258
+ const request = {
259
+ 'op': 'order.amend',
260
+ 'reqId': requestId,
261
+ 'args': [
262
+ orderRequest,
263
+ ],
264
+ 'header': {
265
+ 'X-BAPI-TIMESTAMP': this.milliseconds().toString(),
266
+ 'X-BAPI-RECV-WINDOW': this.options['recvWindow'].toString(),
267
+ },
268
+ };
269
+ return await this.watch(url, requestId, request, requestId, true);
270
+ }
271
+ async cancelOrderWs(id, symbol = undefined, params = {}) {
272
+ /**
273
+ * @method
274
+ * @name bybit#cancelOrderWs
275
+ * @description cancels an open order
276
+ * @see https://bybit-exchange.github.io/docs/v5/order/cancel-order
277
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
278
+ * @param {string} id order id
279
+ * @param {string} symbol unified symbol of the market the order was made in
280
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
281
+ * @param {boolean} [params.stop] *spot only* whether the order is a stop order
282
+ * @param {string} [params.orderFilter] *spot only* 'Order' or 'StopOrder' or 'tpslOrder'
283
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
284
+ */
285
+ await this.loadMarkets();
286
+ const orderRequest = this.cancelOrderRequest(id, symbol, params);
287
+ const url = this.urls['api']['ws']['private']['trade'];
288
+ await this.authenticate(url);
289
+ const requestId = this.requestId().toString();
290
+ delete orderRequest['orderFilter'];
291
+ const request = {
292
+ 'op': 'order.cancel',
293
+ 'reqId': requestId,
294
+ 'args': [
295
+ orderRequest,
296
+ ],
297
+ 'header': {
298
+ 'X-BAPI-TIMESTAMP': this.milliseconds().toString(),
299
+ 'X-BAPI-RECV-WINDOW': this.options['recvWindow'].toString(),
300
+ },
301
+ };
302
+ return await this.watch(url, requestId, request, requestId, true);
303
+ }
175
304
  async watchTicker(symbol, params = {}) {
176
305
  /**
177
306
  * @method
@@ -1104,6 +1233,32 @@ export default class bybit extends bybitRest {
1104
1233
  }
1105
1234
  return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
1106
1235
  }
1236
+ handleOrderWs(client, message) {
1237
+ //
1238
+ // {
1239
+ // "reqId":"1",
1240
+ // "retCode":0,
1241
+ // "retMsg":"OK",
1242
+ // "op":"order.create",
1243
+ // "data":{
1244
+ // "orderId":"1673523595617593600",
1245
+ // "orderLinkId":"1673523595617593601"
1246
+ // },
1247
+ // "header":{
1248
+ // "X-Bapi-Limit":"20",
1249
+ // "X-Bapi-Limit-Status":"19",
1250
+ // "X-Bapi-Limit-Reset-Timestamp":"1714235558880",
1251
+ // "Traceid":"584a06d373f2fdcb3a4dfdd81d27df11",
1252
+ // "Timenow":"1714235558881"
1253
+ // },
1254
+ // "connId":"cojidqec0hv9fgvhtbt0-40e"
1255
+ // }
1256
+ //
1257
+ const messageHash = this.safeString(message, 'reqId');
1258
+ const data = this.safeDict(message, 'data');
1259
+ const order = this.parseOrder(data);
1260
+ client.resolve(order, messageHash);
1261
+ }
1107
1262
  handleOrder(client, message) {
1108
1263
  //
1109
1264
  // spot
@@ -1711,11 +1866,32 @@ export default class bybit extends bybitRest {
1711
1866
  //
1712
1867
  // { code: '-10009', desc: "Invalid period!" }
1713
1868
  //
1714
- const code = this.safeString2(message, 'code', 'ret_code');
1869
+ // {
1870
+ // "reqId":"1",
1871
+ // "retCode":170131,
1872
+ // "retMsg":"Insufficient balance.",
1873
+ // "op":"order.create",
1874
+ // "data":{
1875
+ //
1876
+ // },
1877
+ // "header":{
1878
+ // "X-Bapi-Limit":"20",
1879
+ // "X-Bapi-Limit-Status":"19",
1880
+ // "X-Bapi-Limit-Reset-Timestamp":"1714236608944",
1881
+ // "Traceid":"3d7168a137bf32a947b7e5e6a575ac7f",
1882
+ // "Timenow":"1714236608946"
1883
+ // },
1884
+ // "connId":"cojifin88smerbj9t560-406"
1885
+ // }
1886
+ //
1887
+ const code = this.safeStringN(message, ['code', 'ret_code', 'retCode']);
1715
1888
  try {
1716
- if (code !== undefined) {
1889
+ if (code !== undefined && code !== '0') {
1717
1890
  const feedback = this.id + ' ' + this.json(message);
1718
1891
  this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
1892
+ const msg = this.safeString2(message, 'retMsg', 'ret_msg');
1893
+ this.throwBroadlyMatchedException(this.exceptions['broad'], msg, feedback);
1894
+ throw new ExchangeError(feedback);
1719
1895
  }
1720
1896
  const success = this.safeValue(message, 'success');
1721
1897
  if (success !== undefined && !success) {
@@ -1740,7 +1916,8 @@ export default class bybit extends bybitRest {
1740
1916
  }
1741
1917
  }
1742
1918
  else {
1743
- client.reject(error);
1919
+ const messageHash = this.safeString(message, 'reqId');
1920
+ client.reject(error, messageHash);
1744
1921
  }
1745
1922
  return true;
1746
1923
  }
@@ -1762,17 +1939,12 @@ export default class bybit extends bybitRest {
1762
1939
  return;
1763
1940
  }
1764
1941
  // pong
1765
- const op = this.safeString(message, 'op');
1766
- if (op === 'pong') {
1767
- this.handlePong(client, message);
1768
- return;
1769
- }
1770
1942
  const event = this.safeString(message, 'event');
1771
1943
  if (event === 'sub') {
1772
1944
  this.handleSubscriptionStatus(client, message);
1773
1945
  return;
1774
1946
  }
1775
- const topic = this.safeString(message, 'topic', '');
1947
+ const topic = this.safeString2(message, 'topic', 'op');
1776
1948
  const methods = {
1777
1949
  'orderbook': this.handleOrderBook,
1778
1950
  'kline': this.handleOHLCV,
@@ -1788,6 +1960,11 @@ export default class bybit extends bybitRest {
1788
1960
  'ticketInfo': this.handleMyTrades,
1789
1961
  'user.openapi.perp.trade': this.handleMyTrades,
1790
1962
  'position': this.handlePositions,
1963
+ 'pong': this.handlePong,
1964
+ 'order.create': this.handleOrderWs,
1965
+ 'order.amend': this.handleOrderWs,
1966
+ 'order.cancel': this.handleOrderWs,
1967
+ 'auth': this.handleAuthenticate,
1791
1968
  };
1792
1969
  const exacMethod = this.safeValue(methods, topic);
1793
1970
  if (exacMethod !== undefined) {
@@ -1805,7 +1982,7 @@ export default class bybit extends bybitRest {
1805
1982
  }
1806
1983
  // unified auth acknowledgement
1807
1984
  const type = this.safeString(message, 'type');
1808
- if ((op === 'auth') || (type === 'AUTH_RESP')) {
1985
+ if (type === 'AUTH_RESP') {
1809
1986
  this.handleAuthenticate(client, message);
1810
1987
  }
1811
1988
  }
@@ -1838,9 +2015,17 @@ export default class bybit extends bybitRest {
1838
2015
  // "conn_id": "ce3dpomvha7dha97tvp0-2xh"
1839
2016
  // }
1840
2017
  //
2018
+ // {
2019
+ // "retCode":0,
2020
+ // "retMsg":"OK",
2021
+ // "op":"auth",
2022
+ // "connId":"cojifin88smerbj9t560-404"
2023
+ // }
2024
+ //
1841
2025
  const success = this.safeValue(message, 'success');
2026
+ const code = this.safeInteger(message, 'retCode');
1842
2027
  const messageHash = 'authenticated';
1843
- if (success) {
2028
+ if (success || code === 0) {
1844
2029
  const future = this.safeValue(client.futures, messageHash);
1845
2030
  future.resolve(true);
1846
2031
  }
@@ -3,13 +3,17 @@ import { Strings, Tickers, Ticker, Int, Trade, OrderBook, Order, Str } from '../
3
3
  export default class coinbase extends coinbaseRest {
4
4
  describe(): any;
5
5
  subscribe(name: string, isPrivate: boolean, symbol?: any, params?: {}): Promise<any>;
6
+ subscribeMultiple(name: string, isPrivate: boolean, symbols?: Strings, params?: {}): Promise<any>;
7
+ createWSAuth(name: string, productIds: string[]): {};
6
8
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
7
9
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
8
10
  handleTickers(client: any, message: any): any;
9
11
  parseWsTicker(ticker: any, market?: any): Ticker;
10
12
  watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
13
+ watchTradesForSymbols(symbols: string[], since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
11
14
  watchOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
12
15
  watchOrderBook(symbol: string, limit?: Int, params?: {}): Promise<OrderBook>;
16
+ watchOrderBookForSymbols(symbols: string[], limit?: Int, params?: {}): Promise<OrderBook>;
13
17
  handleTrade(client: any, message: any): any;
14
18
  handleOrder(client: any, message: any): any;
15
19
  parseWsOrder(order: any, market?: any): Order;