ccxt 4.1.9 → 4.1.11

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 (76) hide show
  1. package/.git-templates/hooks/pre-push +55 -0
  2. package/CONTRIBUTING.md +2 -0
  3. package/README.md +3 -3
  4. package/build.sh +3 -1
  5. package/dist/ccxt.browser.js +433 -191
  6. package/dist/ccxt.browser.min.js +3 -3
  7. package/dist/cjs/ccxt.js +1 -1
  8. package/dist/cjs/src/base/Exchange.js +31 -3
  9. package/dist/cjs/src/binance.js +21 -10
  10. package/dist/cjs/src/bingx.js +18 -11
  11. package/dist/cjs/src/bitbns.js +107 -83
  12. package/dist/cjs/src/bitget.js +11 -17
  13. package/dist/cjs/src/bitmart.js +2 -2
  14. package/dist/cjs/src/btcalpha.js +9 -1
  15. package/dist/cjs/src/btcmarkets.js +5 -5
  16. package/dist/cjs/src/bybit.js +2 -2
  17. package/dist/cjs/src/coinex.js +17 -5
  18. package/dist/cjs/src/coinspot.js +103 -8
  19. package/dist/cjs/src/delta.js +2 -2
  20. package/dist/cjs/src/deribit.js +7 -1
  21. package/dist/cjs/src/hitbtc.js +20 -2
  22. package/dist/cjs/src/huobi.js +5 -6
  23. package/dist/cjs/src/okx.js +3 -3
  24. package/dist/cjs/src/phemex.js +20 -1
  25. package/dist/cjs/src/pro/binance.js +3 -9
  26. package/dist/cjs/src/pro/phemex.js +2 -2
  27. package/dist/cjs/src/probit.js +3 -0
  28. package/dist/cjs/src/whitebit.js +14 -11
  29. package/dist/cjs/src/woo.js +21 -1
  30. package/js/ccxt.d.ts +1 -1
  31. package/js/ccxt.js +1 -1
  32. package/js/src/abstract/binance.d.ts +3 -0
  33. package/js/src/abstract/binancecoinm.d.ts +3 -0
  34. package/js/src/abstract/binanceus.d.ts +3 -0
  35. package/js/src/abstract/binanceusdm.d.ts +3 -0
  36. package/js/src/abstract/bingx.d.ts +1 -0
  37. package/js/src/base/Exchange.d.ts +7 -6
  38. package/js/src/base/Exchange.js +31 -3
  39. package/js/src/base/types.d.ts +10 -0
  40. package/js/src/binance.d.ts +5 -13
  41. package/js/src/binance.js +21 -10
  42. package/js/src/bingx.d.ts +2 -16
  43. package/js/src/bingx.js +18 -11
  44. package/js/src/bitbns.d.ts +1 -1
  45. package/js/src/bitbns.js +107 -83
  46. package/js/src/bitget.d.ts +2 -16
  47. package/js/src/bitget.js +11 -17
  48. package/js/src/bitmart.d.ts +2 -16
  49. package/js/src/bitmart.js +2 -2
  50. package/js/src/btcalpha.js +9 -1
  51. package/js/src/btcmarkets.js +5 -5
  52. package/js/src/bybit.d.ts +5 -19
  53. package/js/src/bybit.js +2 -2
  54. package/js/src/coinex.d.ts +1 -1
  55. package/js/src/coinex.js +17 -5
  56. package/js/src/coinspot.d.ts +1 -0
  57. package/js/src/coinspot.js +103 -8
  58. package/js/src/delta.d.ts +2 -20
  59. package/js/src/delta.js +2 -2
  60. package/js/src/deribit.js +7 -1
  61. package/js/src/gate.d.ts +2 -2
  62. package/js/src/hitbtc.d.ts +2 -2
  63. package/js/src/hitbtc.js +20 -2
  64. package/js/src/huobi.d.ts +3 -12
  65. package/js/src/huobi.js +5 -6
  66. package/js/src/okx.d.ts +3 -21
  67. package/js/src/okx.js +3 -3
  68. package/js/src/phemex.js +20 -1
  69. package/js/src/pro/binance.js +3 -9
  70. package/js/src/pro/phemex.js +2 -2
  71. package/js/src/probit.js +3 -0
  72. package/js/src/whitebit.js +14 -11
  73. package/js/src/woo.js +21 -1
  74. package/package.json +2 -2
  75. package/pyproject.toml +8 -0
  76. package/skip-tests.json +1 -1
package/dist/cjs/ccxt.js CHANGED
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
180
180
 
181
181
  //-----------------------------------------------------------------------------
182
182
  // this is updated by vss.js when building
183
- const version = '4.1.9';
183
+ const version = '4.1.11';
184
184
  Exchange["default"].ccxtVersion = version;
185
185
  const exchanges = {
186
186
  'ace': ace,
@@ -2101,7 +2101,7 @@ class Exchange {
2101
2101
  // string = true
2102
2102
  //
2103
2103
  // [
2104
- // { 'currency': 'BTC', 'cost': '0.3' },
2104
+ // { 'currency': 'BTC', 'cost': '0.4' },
2105
2105
  // { 'currency': 'BTC', 'cost': '0.6', 'rate': '0.00123' },
2106
2106
  // { 'currency': 'BTC', 'cost': '0.5', 'rate': '0.00456' },
2107
2107
  // { 'currency': 'USDT', 'cost': '12.3456' },
@@ -2325,7 +2325,7 @@ class Exchange {
2325
2325
  }
2326
2326
  return result;
2327
2327
  }
2328
- marketSymbols(symbols, type = undefined, allowEmpty = true) {
2328
+ marketSymbols(symbols, type = undefined, allowEmpty = true, sameTypeOnly = false, sameSubTypeOnly = false) {
2329
2329
  if (symbols === undefined) {
2330
2330
  if (!allowEmpty) {
2331
2331
  throw new errors.ArgumentsRequired(this.id + ' empty list of symbols is not supported');
@@ -2340,10 +2340,26 @@ class Exchange {
2340
2340
  return symbols;
2341
2341
  }
2342
2342
  const result = [];
2343
+ let marketType = undefined;
2344
+ let isLinearSubType = undefined;
2343
2345
  for (let i = 0; i < symbols.length; i++) {
2344
2346
  const market = this.market(symbols[i]);
2347
+ if (sameTypeOnly && (marketType !== undefined)) {
2348
+ if (market['type'] !== marketType) {
2349
+ throw new errors.BadRequest(this.id + ' symbols must be of the same type, either ' + marketType + ' or ' + market['type'] + '.');
2350
+ }
2351
+ }
2352
+ if (sameSubTypeOnly && (isLinearSubType !== undefined)) {
2353
+ if (market['linear'] !== isLinearSubType) {
2354
+ throw new errors.BadRequest(this.id + ' symbols must be of the same subType, either linear or inverse.');
2355
+ }
2356
+ }
2345
2357
  if (type !== undefined && market['type'] !== type) {
2346
- throw new errors.BadRequest(this.id + ' symbols must be of same type ' + type + '. If the type is incorrect you can change it in options or the params of the request');
2358
+ throw new errors.BadRequest(this.id + ' symbols must be of the same type ' + type + '. If the type is incorrect you can change it in options or the params of the request');
2359
+ }
2360
+ marketType = market['type'];
2361
+ if (!market['spot']) {
2362
+ isLinearSubType = market['linear'];
2347
2363
  }
2348
2364
  const symbol = this.safeString(market, 'symbol', symbols[i]);
2349
2365
  result.push(symbol);
@@ -4372,6 +4388,18 @@ class Exchange {
4372
4388
  }
4373
4389
  return [request, params];
4374
4390
  }
4391
+ safeOpenInterest(interest, market = undefined) {
4392
+ return this.extend(interest, {
4393
+ 'symbol': this.safeString(market, 'symbol'),
4394
+ 'baseVolume': this.safeNumber(interest, 'baseVolume'),
4395
+ 'quoteVolume': this.safeNumber(interest, 'quoteVolume'),
4396
+ 'openInterestAmount': this.safeNumber(interest, 'openInterestAmount'),
4397
+ 'openInterestValue': this.safeNumber(interest, 'openInterestValue'),
4398
+ 'timestamp': this.safeInteger(interest, 'timestamp'),
4399
+ 'datetime': this.safeString(interest, 'datetime'),
4400
+ 'info': this.safeValue(interest, 'info'),
4401
+ });
4402
+ }
4375
4403
  }
4376
4404
 
4377
4405
  exports.Exchange = Exchange;
@@ -22,7 +22,7 @@ class binance extends binance$1 {
22
22
  'rateLimit': 50,
23
23
  'certified': true,
24
24
  'pro': true,
25
- // new metainfo interface
25
+ // new metainfo2 interface
26
26
  'has': {
27
27
  'CORS': undefined,
28
28
  'spot': true,
@@ -249,6 +249,7 @@ class binance extends binance$1 {
249
249
  'loan/vip/loanable/data': 40,
250
250
  'loan/vip/collateral/data': 40,
251
251
  'loan/vip/request/data': 2.6668,
252
+ 'loan/vip/request/interestRate': 2.6668,
252
253
  'loan/income': 40.002,
253
254
  'loan/ongoing/orders': 40,
254
255
  'loan/ltv/adjustment/history': 40,
@@ -763,10 +764,12 @@ class binance extends binance$1 {
763
764
  'adlQuantile': 5,
764
765
  'pmAccountInfo': 5,
765
766
  'orderAmendment': 1,
766
- 'order/asyn': 5,
767
- 'order/asyn/id': 5,
768
- 'trade/asyn': 5,
769
- 'trade/asyn/id': 5,
767
+ 'income/asyn': 1000,
768
+ 'income/asyn/id': 10,
769
+ 'order/asyn': 1000,
770
+ 'order/asyn/id': 10,
771
+ 'trade/asyn': 1000,
772
+ 'trade/asyn/id': 10,
770
773
  },
771
774
  'post': {
772
775
  'batchOrders': 5,
@@ -2385,6 +2388,7 @@ class binance extends binance$1 {
2385
2388
  },
2386
2389
  },
2387
2390
  'info': market,
2391
+ 'created': this.safeInteger(market, 'onboardDate'), // present in inverse & linear apis
2388
2392
  };
2389
2393
  if ('PRICE_FILTER' in filtersByType) {
2390
2394
  const filter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
@@ -2712,7 +2716,7 @@ class binance extends binance$1 {
2712
2716
  // "unrealizedProfit":"0.00000000",
2713
2717
  // "positionInitialMargin":"0",
2714
2718
  // "openOrderInitialMargin":"0",
2715
- // "leverage":"20",
2719
+ // "leverage":"21",
2716
2720
  // "isolated":false,
2717
2721
  // "entryPrice":"0.00000",
2718
2722
  // "maxNotional":"5000000",
@@ -3214,6 +3218,7 @@ class binance extends binance$1 {
3214
3218
  await this.loadMarkets();
3215
3219
  let type = undefined;
3216
3220
  let market = undefined;
3221
+ symbols = this.marketSymbols(symbols, undefined, true, true, true);
3217
3222
  if (symbols !== undefined) {
3218
3223
  const first = this.safeString(symbols, 0);
3219
3224
  market = this.market(first);
@@ -8386,7 +8391,7 @@ class binance extends binance$1 {
8386
8391
  throw new errors.AuthenticationError(this.id + ' userDataStream endpoint requires `apiKey` credential');
8387
8392
  }
8388
8393
  }
8389
- else if ((api === 'private') || (api === 'eapiPrivate') || (api === 'sapi' && path !== 'system/status') || (api === 'sapiV2') || (api === 'sapiV3') || (api === 'sapiV4') || (api === 'wapi' && path !== 'systemStatus') || (api === 'dapiPrivate') || (api === 'dapiPrivateV2') || (api === 'fapiPrivate') || (api === 'fapiPrivateV2')) {
8394
+ else if ((api === 'private') || (api === 'eapiPrivate') || (api === 'sapi' && path !== 'system/status') || (api === 'sapiV2') || (api === 'sapiV3') || (api === 'sapiV4') || (api === 'wapi' && path !== 'systemStatus') || (api === 'dapiPrivate') || (api === 'dapiPrivateV2') || (api === 'fapiPrivate') || (api === 'fapiPrivateV2') || (api === 'papi')) {
8390
8395
  this.checkRequiredCredentials();
8391
8396
  if (method === 'POST' && ((path === 'order') || (path === 'sor/order'))) {
8392
8397
  // inject in implicit API calls
@@ -9141,7 +9146,13 @@ class binance extends binance$1 {
9141
9146
  // ]
9142
9147
  //
9143
9148
  if (market['option']) {
9144
- return this.parseOpenInterests(response, market);
9149
+ const result = this.parseOpenInterests(response, market);
9150
+ for (let i = 0; i < result.length; i++) {
9151
+ const item = result[i];
9152
+ if (item['symbol'] === symbol) {
9153
+ return item;
9154
+ }
9155
+ }
9145
9156
  }
9146
9157
  else {
9147
9158
  return this.parseOpenInterest(response, market);
@@ -9154,7 +9165,7 @@ class binance extends binance$1 {
9154
9165
  const value = this.safeNumber2(interest, 'sumOpenInterestValue', 'sumOpenInterestUsd');
9155
9166
  // Inverse returns the number of contracts different from the base or quote volume in this case
9156
9167
  // compared with https://www.binance.com/en/futures/funding-history/quarterly/4
9157
- return {
9168
+ return this.safeOpenInterest({
9158
9169
  'symbol': this.safeSymbol(id, market, undefined, 'contract'),
9159
9170
  'baseVolume': market['inverse'] ? undefined : amount,
9160
9171
  'quoteVolume': value,
@@ -9163,7 +9174,7 @@ class binance extends binance$1 {
9163
9174
  'timestamp': timestamp,
9164
9175
  'datetime': this.iso8601(timestamp),
9165
9176
  'info': interest,
9166
- };
9177
+ }, market);
9167
9178
  }
9168
9179
  }
9169
9180
 
@@ -173,6 +173,13 @@ class bingx extends bingx$1 {
173
173
  },
174
174
  },
175
175
  },
176
+ 'v3': {
177
+ 'public': {
178
+ 'get': {
179
+ 'quote/klines': 1,
180
+ },
181
+ },
182
+ },
176
183
  },
177
184
  'contract': {
178
185
  'v1': {
@@ -630,12 +637,12 @@ class bingx extends bingx$1 {
630
637
  * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
631
638
  * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#K-Line%20Data
632
639
  * @see https://bingx-api.github.io/docs/#/spot/market-api.html#Candlestick%20chart%20data
640
+ * @see https://bingx-api.github.io/docs/#/swapV2/market-api.html#%20K-Line%20Data
633
641
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
634
642
  * @param {string} timeframe the length of time each candle represents
635
643
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
636
644
  * @param {int} [limit] the maximum amount of candles to fetch
637
645
  * @param {object} [params] extra parameters specific to the bingx api endpoint
638
- * @param {string} [params.price] "mark" or "index" for mark price and index price candles
639
646
  * @param {int} [params.until] timestamp in ms of the latest candle to fetch
640
647
  * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
641
648
  * @returns {[[int]]} A list of candles ordered as timestamp, open, high, low, close, volume
@@ -657,20 +664,17 @@ class bingx extends bingx$1 {
657
664
  if (limit !== undefined) {
658
665
  request['limit'] = limit;
659
666
  }
660
- else {
661
- request['limit'] = 50;
662
- }
663
- const until = this.safeInteger2(params, 'until', 'startTime');
667
+ const until = this.safeInteger2(params, 'until', 'endTime');
664
668
  if (until !== undefined) {
665
669
  params = this.omit(params, ['until']);
666
- request['startTime'] = until;
670
+ request['endTime'] = until;
667
671
  }
668
672
  let response = undefined;
669
673
  if (market['spot']) {
670
674
  response = await this.spotV1PublicGetMarketKline(this.extend(request, params));
671
675
  }
672
676
  else {
673
- response = await this.swapV2PublicGetQuoteKlines(this.extend(request, params));
677
+ response = await this.swapV3PublicGetQuoteKlines(this.extend(request, params));
674
678
  }
675
679
  //
676
680
  // {
@@ -1171,14 +1175,16 @@ class bingx extends bingx$1 {
1171
1175
  const id = this.safeString(interest, 'symbol');
1172
1176
  const symbol = this.safeSymbol(id, market, '-', 'swap');
1173
1177
  const openInterest = this.safeNumber(interest, 'openInterest');
1174
- return {
1178
+ return this.safeOpenInterest({
1175
1179
  'symbol': symbol,
1180
+ 'baseVolume': undefined,
1181
+ 'quoteVolume': undefined,
1176
1182
  'openInterestAmount': undefined,
1177
1183
  'openInterestValue': openInterest,
1178
1184
  'timestamp': timestamp,
1179
1185
  'datetime': this.iso8601(timestamp),
1180
1186
  'info': interest,
1181
- };
1187
+ }, market);
1182
1188
  }
1183
1189
  async fetchTicker(symbol, params = {}) {
1184
1190
  /**
@@ -1551,8 +1557,9 @@ class bingx extends bingx$1 {
1551
1557
  'liquidationPrice': undefined,
1552
1558
  'entryPrice': this.safeNumber2(position, 'avgPrice', 'entryPrice'),
1553
1559
  'unrealizedPnl': this.safeNumber(position, 'unrealizedProfit'),
1560
+ 'realizedPnl': this.safeNumber(position, 'realisedProfit'),
1554
1561
  'percentage': undefined,
1555
- 'contracts': undefined,
1562
+ 'contracts': this.safeNumber(position, 'positionAmt'),
1556
1563
  'contractSize': undefined,
1557
1564
  'markPrice': undefined,
1558
1565
  'lastPrice': undefined,
@@ -1563,7 +1570,7 @@ class bingx extends bingx$1 {
1563
1570
  'lastUpdateTimestamp': undefined,
1564
1571
  'maintenanceMargin': undefined,
1565
1572
  'maintenanceMarginPercentage': undefined,
1566
- 'collateral': this.safeString(position, 'positionAmt'),
1573
+ 'collateral': this.safeNumber(position, 'positionAmt'),
1567
1574
  'initialMargin': this.safeNumber(position, 'initialMargin'),
1568
1575
  'initialMarginPercentage': undefined,
1569
1576
  'leverage': this.safeNumber(position, 'leverage'),
@@ -479,9 +479,12 @@ class bitbns extends bitbns$1 {
479
479
  // note that "Money" stands for INR - the only fiat in bitbns
480
480
  return this.parseBalance(response);
481
481
  }
482
- parseOrderStatus(status) {
482
+ parseStatus(status) {
483
483
  const statuses = {
484
+ '-1': 'cancelled',
484
485
  '0': 'open',
486
+ '1': 'open',
487
+ '2': 'done',
485
488
  // 'PARTIALLY_FILLED': 'open',
486
489
  // 'FILLED': 'closed',
487
490
  // 'CANCELED': 'canceled',
@@ -496,90 +499,78 @@ class bitbns extends bitbns$1 {
496
499
  // createOrder
497
500
  //
498
501
  // {
499
- // "data":"Successfully placed bid to purchase currency",
500
- // "status":1,
501
- // "error":null,
502
- // "id":5424475,
503
- // "code":200
502
+ // "data": "Successfully placed bid to purchase currency",
503
+ // "status": 1,
504
+ // "error": null,
505
+ // "id": 5424475,
506
+ // "code": 200
504
507
  // }
505
508
  //
506
- // fetchOrder
509
+ // fetchOpenOrders, fetchOrder
507
510
  //
508
- // {
509
- // "entry_id":5424475,
510
- // "btc":0.01,
511
- // "rate":2000,
512
- // "time":"2021-04-25T17:05:42.000Z",
513
- // "type":0,
514
- // "status":0,
515
- // "total":0.01,
516
- // "avg_cost":null,
517
- // "side":"BUY",
518
- // "amount":0.01,
519
- // "remaining":0.01,
520
- // "filled":0,
521
- // "cost":null,
522
- // "fee":0.05
523
- // }
511
+ // {
512
+ // "entry_id": 5424475,
513
+ // "btc": 0.01,
514
+ // "rate": 2000,
515
+ // "time": "2021-04-25T17:05:42.000Z",
516
+ // "type": 0,
517
+ // "status": 0
518
+ // "t_rate": 0.45, // only stop orders
519
+ // "trail": 0 // only stop orders
520
+ // }
524
521
  //
525
- // fetchOpenOrders
522
+ // cancelOrder
526
523
  //
527
- // {
528
- // "entry_id":5424475,
529
- // "btc":0.01,
530
- // "rate":2000,
531
- // "time":"2021-04-25T17:05:42.000Z",
532
- // "type":0,
533
- // "status":0
534
- // }
524
+ // {
525
+ // "data": "Successfully cancelled the order",
526
+ // "status": 1,
527
+ // "error": null,
528
+ // "code": 200
529
+ // }
535
530
  //
536
531
  const id = this.safeString2(order, 'id', 'entry_id');
537
- const marketId = this.safeString(order, 'symbol');
538
- const symbol = this.safeSymbol(marketId, market);
539
- const timestamp = this.parse8601(this.safeString(order, 'time'));
540
- const price = this.safeString(order, 'rate');
541
- const amount = this.safeString2(order, 'amount', 'btc');
542
- const filled = this.safeString(order, 'filled');
543
- const remaining = this.safeString(order, 'remaining');
544
- const average = this.safeString(order, 'avg_cost');
545
- const cost = this.safeString(order, 'cost');
546
- let type = this.safeStringLower(order, 'type');
547
- if (type === '0') {
548
- type = 'limit';
532
+ const datetime = this.safeString(order, 'time');
533
+ const triggerPrice = this.safeString(order, 't_rate');
534
+ let side = this.safeString(order, 'type');
535
+ if (side === '0') {
536
+ side = 'buy';
549
537
  }
550
- const status = this.parseOrderStatus(this.safeString(order, 'status'));
551
- const side = this.safeStringLower(order, 'side');
552
- const feeCost = this.safeNumber(order, 'fee');
553
- let fee = undefined;
554
- if (feeCost !== undefined) {
555
- const feeCurrencyCode = undefined;
556
- fee = {
557
- 'cost': feeCost,
558
- 'currency': feeCurrencyCode,
559
- };
538
+ else if (side === '1') {
539
+ side = 'sell';
540
+ }
541
+ const data = this.safeString(order, 'data');
542
+ let status = this.safeString(order, 'status');
543
+ if (data === 'Successfully cancelled the order') {
544
+ status = 'cancelled';
545
+ }
546
+ else {
547
+ status = this.parseStatus(status);
560
548
  }
561
549
  return this.safeOrder({
562
550
  'info': order,
563
551
  'id': id,
564
552
  'clientOrderId': undefined,
565
- 'timestamp': timestamp,
566
- 'datetime': this.iso8601(timestamp),
553
+ 'timestamp': this.parse8601(datetime),
554
+ 'datetime': datetime,
567
555
  'lastTradeTimestamp': undefined,
568
- 'symbol': symbol,
569
- 'type': type,
556
+ 'symbol': this.safeString(market, 'symbol'),
570
557
  'timeInForce': undefined,
571
558
  'postOnly': undefined,
572
559
  'side': side,
573
- 'price': price,
574
- 'stopPrice': undefined,
575
- 'triggerPrice': undefined,
576
- 'amount': amount,
577
- 'cost': cost,
578
- 'average': average,
579
- 'filled': filled,
580
- 'remaining': remaining,
560
+ 'price': this.safeString(order, 'rate'),
561
+ 'stopPrice': triggerPrice,
562
+ 'triggerPrice': triggerPrice,
563
+ 'amount': this.safeString(order, 'btc'),
564
+ 'cost': undefined,
565
+ 'average': undefined,
566
+ 'filled': undefined,
567
+ 'remaining': undefined,
581
568
  'status': status,
582
- 'fee': fee,
569
+ 'fee': {
570
+ 'cost': undefined,
571
+ 'currency': undefined,
572
+ 'rate': undefined,
573
+ },
583
574
  'trades': undefined,
584
575
  }, market);
585
576
  }
@@ -588,19 +579,27 @@ class bitbns extends bitbns$1 {
588
579
  * @method
589
580
  * @name bitbns#createOrder
590
581
  * @description create a trade order
582
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-2/place-orders
583
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-1/market-orders-quantity // market orders
591
584
  * @param {string} symbol unified symbol of the market to create an order in
592
585
  * @param {string} type 'market' or 'limit'
593
586
  * @param {string} side 'buy' or 'sell'
594
587
  * @param {float} amount how much of currency you want to trade in units of base currency
595
588
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
596
589
  * @param {object} [params] extra parameters specific to the bitbns api endpoint
590
+ * @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
591
+ *
592
+ * EXCHANGE SPECIFIC PARAMETERS
593
+ * @param {float} [params.target_rate] *requires params.trail_rate when set, type must be 'limit'* a bracket order is placed when set
594
+ * @param {float} [params.trail_rate] *requires params.target_rate when set, type must be 'limit'* a bracket order is placed when set
597
595
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
598
596
  */
599
- if (type !== 'limit' && type !== 'market') {
600
- throw new errors.ExchangeError(this.id + ' allows limit and market orders only');
601
- }
602
597
  await this.loadMarkets();
603
598
  const market = this.market(symbol);
599
+ const triggerPrice = this.safeStringN(params, ['triggerPrice', 'stopPrice', 't_rate']);
600
+ const targetRate = this.safeString(params, 'target_rate');
601
+ const trailRate = this.safeString(params, 'trail_rate');
602
+ params = this.omit(params, ['triggerPrice', 'stopPrice', 'trail_rate', 'target_rate', 't_rate']);
604
603
  const request = {
605
604
  'side': side.toUpperCase(),
606
605
  'symbol': market['uppercaseId'],
@@ -608,20 +607,23 @@ class bitbns extends bitbns$1 {
608
607
  // 'target_rate': this.priceToPrecision (symbol, targetRate),
609
608
  // 't_rate': this.priceToPrecision (symbol, stopPrice),
610
609
  // 'trail_rate': this.priceToPrecision (symbol, trailRate),
611
- // To Place Simple Buy or Sell Order use rate
612
- // To Place Stoploss Buy or Sell Order use rate & t_rate
613
- // To Place Bracket Buy or Sell Order use rate , t_rate, target_rate & trail_rate
614
610
  };
615
611
  let method = 'v2PostOrders';
616
612
  if (type === 'limit') {
617
613
  request['rate'] = this.priceToPrecision(symbol, price);
618
614
  }
619
- else if (type === 'market') {
615
+ else {
620
616
  method = 'v1PostPlaceMarketOrderQntySymbol';
621
617
  request['market'] = market['quoteId'];
622
618
  }
623
- else {
624
- throw new errors.ExchangeError(this.id + ' allows limit and market orders only');
619
+ if (triggerPrice !== undefined) {
620
+ request['t_rate'] = this.priceToPrecision(symbol, triggerPrice);
621
+ }
622
+ if (targetRate !== undefined) {
623
+ request['target_rate'] = this.priceToPrecision(symbol, targetRate);
624
+ }
625
+ if (trailRate !== undefined) {
626
+ request['trail_rate'] = this.priceToPrecision(symbol, trailRate);
625
627
  }
626
628
  const response = await this[method](this.extend(request, params));
627
629
  //
@@ -640,9 +642,12 @@ class bitbns extends bitbns$1 {
640
642
  * @method
641
643
  * @name bitbns#cancelOrder
642
644
  * @description cancels an open order
645
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-2/cancel-orders
646
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-1/cancel-stop-loss-orders
643
647
  * @param {string} id order id
644
648
  * @param {string} symbol unified symbol of the market the order was made in
645
649
  * @param {object} [params] extra parameters specific to the bitbns api endpoint
650
+ * @param {boolean} [params.trigger] true if cancelling a trigger order
646
651
  * @returns {object} An [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
647
652
  */
648
653
  if (symbol === undefined) {
@@ -650,13 +655,18 @@ class bitbns extends bitbns$1 {
650
655
  }
651
656
  await this.loadMarkets();
652
657
  const market = this.market(symbol);
653
- const quoteSide = (market['quoteId'] === 'USDT') ? 'usdtcancelOrder' : 'cancelOrder';
658
+ const isTrigger = this.safeValue2(params, 'trigger', 'stop');
659
+ params = this.omit(params, ['trigger', 'stop']);
654
660
  const request = {
655
661
  'entry_id': id,
656
662
  'symbol': market['uppercaseId'],
657
- 'side': quoteSide,
658
663
  };
659
- const response = await this.v2PostCancel(this.extend(request, params));
664
+ let response = undefined;
665
+ const tail = isTrigger ? 'StopLossOrder' : 'Order';
666
+ let quoteSide = (market['quoteId'] === 'USDT') ? 'usdtcancel' : 'cancel';
667
+ quoteSide += tail;
668
+ request['side'] = quoteSide;
669
+ response = await this.v2PostCancel(this.extend(request, params));
660
670
  return this.parseOrder(response, market);
661
671
  }
662
672
  async fetchOrder(id, symbol = undefined, params = {}) {
@@ -664,6 +674,8 @@ class bitbns extends bitbns$1 {
664
674
  * @method
665
675
  * @name bitbns#fetchOrder
666
676
  * @description fetches information on an order made by the user
677
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-1/order-status
678
+ * @param {string} id order id
667
679
  * @param {string} symbol unified symbol of the market the order was made in
668
680
  * @param {object} [params] extra parameters specific to the bitbns api endpoint
669
681
  * @returns {object} An [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
@@ -677,6 +689,10 @@ class bitbns extends bitbns$1 {
677
689
  'symbol': market['id'],
678
690
  'entry_id': id,
679
691
  };
692
+ const trigger = this.safeValue2(params, 'trigger', 'stop');
693
+ if (trigger) {
694
+ throw new errors.BadRequest(this.id + ' fetchOrder cannot fetch stop orders');
695
+ }
680
696
  const response = await this.v1PostOrderStatusSymbol(this.extend(request, params));
681
697
  //
682
698
  // {
@@ -712,10 +728,13 @@ class bitbns extends bitbns$1 {
712
728
  * @method
713
729
  * @name bitbns#fetchOpenOrders
714
730
  * @description fetch all unfilled currently open orders
731
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-2/order-status-limit
732
+ * @see https://docs.bitbns.com/bitbns/rest-endpoints/order-apis/version-2/order-status-limit/order-status-stop-limit
715
733
  * @param {string} symbol unified market symbol
716
734
  * @param {int} [since] the earliest time in ms to fetch open orders for
717
- * @param {int} [limit] the maximum number of open orders structures to retrieve
735
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
718
736
  * @param {object} [params] extra parameters specific to the bitbns api endpoint
737
+ * @param {boolean} [params.trigger] true if fetching trigger orders
719
738
  * @returns {Order[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
720
739
  */
721
740
  if (symbol === undefined) {
@@ -723,11 +742,13 @@ class bitbns extends bitbns$1 {
723
742
  }
724
743
  await this.loadMarkets();
725
744
  const market = this.market(symbol);
726
- const quoteSide = (market['quoteId'] === 'USDT') ? 'usdtListOpenOrders' : 'listOpenOrders';
745
+ const isTrigger = this.safeValue2(params, 'trigger', 'stop');
746
+ params = this.omit(params, ['trigger', 'stop']);
747
+ const quoteSide = (market['quoteId'] === 'USDT') ? 'usdtListOpen' : 'listOpen';
727
748
  const request = {
728
749
  'symbol': market['uppercaseId'],
729
- 'side': quoteSide,
730
750
  'page': 0,
751
+ 'side': isTrigger ? (quoteSide + 'StopOrders') : (quoteSide + 'Orders'),
731
752
  };
732
753
  const response = await this.v2PostGetordersnew(this.extend(request, params));
733
754
  //
@@ -740,6 +761,9 @@ class bitbns extends bitbns$1 {
740
761
  // "time":"2021-04-25T17:05:42.000Z",
741
762
  // "type":0,
742
763
  // "status":0
764
+ // "t_rate":0.45, // only stop orders
765
+ // "type":1, // only stop orders
766
+ // "trail":0 // only stop orders
743
767
  // }
744
768
  // ],
745
769
  // "status":1,
@@ -1162,7 +1186,7 @@ class bitbns extends bitbns$1 {
1162
1186
  'body': body,
1163
1187
  };
1164
1188
  const payload = this.stringToBase64(this.json(auth));
1165
- const signature = this.hmac(payload, this.encode(this.secret), sha512.sha512);
1189
+ const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha512.sha512);
1166
1190
  headers['X-BITBNS-PAYLOAD'] = payload;
1167
1191
  headers['X-BITBNS-SIGNATURE'] = signature;
1168
1192
  headers['Content-Type'] = 'application/x-www-form-urlencoded';