ccxt 4.0.108 → 4.0.110

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/src/bybit.js CHANGED
@@ -702,10 +702,11 @@ export default class bybit extends Exchange {
702
702
  '10027': PermissionDenied,
703
703
  '10028': PermissionDenied,
704
704
  '10029': PermissionDenied,
705
+ '12137': InvalidOrder,
705
706
  '12201': BadRequest,
706
707
  '12141': BadRequest,
707
708
  '100028': PermissionDenied,
708
- '110001': InvalidOrder,
709
+ '110001': OrderNotFound,
709
710
  '110003': InvalidOrder,
710
711
  '110004': InsufficientFunds,
711
712
  '110005': InvalidOrder,
@@ -3528,11 +3529,38 @@ export default class bybit extends Exchange {
3528
3529
  if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {
3529
3530
  clientOrderId = undefined;
3530
3531
  }
3532
+ const avgPrice = this.omitZero(this.safeString(order, 'avgPrice'));
3531
3533
  const rawTimeInForce = this.safeString(order, 'timeInForce');
3532
3534
  const timeInForce = this.parseTimeInForce(rawTimeInForce);
3533
3535
  const stopPrice = this.omitZero(this.safeString(order, 'triggerPrice'));
3534
- const takeProfitPrice = this.omitZero(this.safeString(order, 'takeProfit'));
3535
- const stopLossPrice = this.omitZero(this.safeString(order, 'stopLoss'));
3536
+ const reduceOnly = this.safeValue(order, 'reduceOnly');
3537
+ let takeProfitPrice = this.omitZero(this.safeString(order, 'takeProfit'));
3538
+ let stopLossPrice = this.omitZero(this.safeString(order, 'stopLoss'));
3539
+ const triggerDirection = this.safeString(order, 'triggerDirection');
3540
+ const isAscending = (triggerDirection === '1');
3541
+ const isStopOrderType2 = (stopPrice !== undefined) && reduceOnly;
3542
+ if ((stopLossPrice === undefined) && isStopOrderType2) {
3543
+ // check if order is stop order type 2 - stopLossPrice
3544
+ if (isAscending && (side === 'buy')) {
3545
+ // stopLoss order against short position
3546
+ stopLossPrice = stopPrice;
3547
+ }
3548
+ if (!isAscending && (side === 'sell')) {
3549
+ // stopLoss order against a long position
3550
+ stopLossPrice = stopPrice;
3551
+ }
3552
+ }
3553
+ if ((takeProfitPrice === undefined) && isStopOrderType2) {
3554
+ // check if order is stop order type 2 - takeProfitPrice
3555
+ if (isAscending && (side === 'sell')) {
3556
+ // takeprofit order against a long position
3557
+ takeProfitPrice = stopPrice;
3558
+ }
3559
+ if (!isAscending && (side === 'buy')) {
3560
+ // takeprofit order against a short position
3561
+ takeProfitPrice = stopPrice;
3562
+ }
3563
+ }
3536
3564
  return this.safeOrder({
3537
3565
  'info': order,
3538
3566
  'id': id,
@@ -3554,7 +3582,7 @@ export default class bybit extends Exchange {
3554
3582
  'stopLossPrice': stopLossPrice,
3555
3583
  'amount': amount,
3556
3584
  'cost': cost,
3557
- 'average': undefined,
3585
+ 'average': avgPrice,
3558
3586
  'filled': filled,
3559
3587
  'remaining': remaining,
3560
3588
  'status': status,
@@ -3606,6 +3634,14 @@ export default class bybit extends Exchange {
3606
3634
  * @param {boolean} [params.isLeverage] *unified spot only* false then spot trading true then margin trading
3607
3635
  * @param {string} [params.tpslMode] *contract only* 'full' or 'partial'
3608
3636
  * @param {string} [params.mmp] *option only* market maker protection
3637
+ * @param {string} [params.triggerDirection] *contract only* the direction for trigger orders, 'up' or 'down'
3638
+ * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
3639
+ * @param {float} [params.stopLossPrice] The price at which a stop loss order is triggered at
3640
+ * @param {float} [params.takeProfitPrice] The price at which a take profit order is triggered at
3641
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
3642
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
3643
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
3644
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
3609
3645
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
3610
3646
  */
3611
3647
  await this.loadMarkets();
@@ -3711,13 +3747,21 @@ export default class bybit extends Exchange {
3711
3747
  const isStopLoss = stopLoss !== undefined;
3712
3748
  const isTakeProfit = takeProfit !== undefined;
3713
3749
  const isBuy = side === 'buy';
3714
- const ascending = stopLossTriggerPrice ? !isBuy : isBuy;
3750
+ const setTriggerDirection = (stopLossTriggerPrice || triggerPrice) ? !isBuy : isBuy;
3751
+ const defaultTriggerDirection = setTriggerDirection ? 2 : 1;
3752
+ const triggerDirection = this.safeString(params, 'triggerDirection');
3753
+ params = this.omit(params, 'triggerDirection');
3754
+ let selectedDirection = defaultTriggerDirection;
3755
+ if (triggerDirection !== undefined) {
3756
+ const isAsending = ((triggerDirection === 'up') || (triggerDirection === '1'));
3757
+ selectedDirection = isAsending ? 1 : 2;
3758
+ }
3715
3759
  if (triggerPrice !== undefined) {
3716
- request['triggerDirection'] = ascending ? 2 : 1;
3760
+ request['triggerDirection'] = selectedDirection;
3717
3761
  request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
3718
3762
  }
3719
3763
  else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
3720
- request['triggerDirection'] = ascending ? 2 : 1;
3764
+ request['triggerDirection'] = selectedDirection;
3721
3765
  triggerPrice = isStopLossTriggerOrder ? stopLossTriggerPrice : takeProfitTriggerPrice;
3722
3766
  request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
3723
3767
  request['reduceOnly'] = true;
package/js/src/phemex.js CHANGED
@@ -1108,9 +1108,10 @@ export default class phemex extends Exchange {
1108
1108
  * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-kline
1109
1109
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1110
1110
  * @param {string} timeframe the length of time each candle represents
1111
- * @param {int} [since] *emulated not supported by the exchange* timestamp in ms of the earliest candle to fetch
1111
+ * @param {int} [since] *only used for USDT settled contracts, otherwise is emulated and not supported by the exchange* timestamp in ms of the earliest candle to fetch
1112
1112
  * @param {int} [limit] the maximum amount of candles to fetch
1113
1113
  * @param {object} [params] extra parameters specific to the phemex api endpoint
1114
+ * @param {int} [params.until] *USDT settled/ linear swaps only* end time in ms
1114
1115
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1115
1116
  */
1116
1117
  await this.loadMarkets();
@@ -1120,34 +1121,55 @@ export default class phemex extends Exchange {
1120
1121
  'symbol': market['id'],
1121
1122
  'resolution': this.safeString(this.timeframes, timeframe, timeframe),
1122
1123
  };
1123
- const possibleLimitValues = [5, 10, 50, 100, 500, 1000];
1124
- const maxLimit = 1000;
1125
- if (limit === undefined && since === undefined) {
1126
- limit = possibleLimitValues[5];
1127
- }
1128
- if (since !== undefined) {
1129
- // phemex also provides kline query with from/to, however, this interface is NOT recommended and does not work properly.
1130
- // we do not send since param to the exchange, instead we calculate appropriate limit param
1131
- const duration = this.parseTimeframe(timeframe) * 1000;
1132
- const timeDelta = this.milliseconds() - since;
1133
- limit = this.parseToInt(timeDelta / duration); // setting limit to the number of candles after since
1134
- }
1135
- if (limit > maxLimit) {
1124
+ const until = this.safeInteger2(params, 'until', 'to');
1125
+ params = this.omit(params, ['until']);
1126
+ const usesSpecialFromToEndpoint = ((market['linear'] || market['settle'] === 'USDT')) && ((since !== undefined) || (until !== undefined));
1127
+ let maxLimit = 1000;
1128
+ if (usesSpecialFromToEndpoint) {
1129
+ maxLimit = 2000;
1130
+ }
1131
+ if (limit === undefined) {
1136
1132
  limit = maxLimit;
1137
1133
  }
1138
- else {
1139
- for (let i = 0; i < possibleLimitValues.length; i++) {
1140
- if (limit <= possibleLimitValues[i]) {
1141
- limit = possibleLimitValues[i];
1142
- }
1143
- }
1144
- }
1145
- request['limit'] = limit;
1134
+ request['limit'] = Math.min(limit, maxLimit);
1146
1135
  let response = undefined;
1147
1136
  if (market['linear'] || market['settle'] === 'USDT') {
1148
- response = await this.publicGetMdV2KlineLast(this.extend(request, params));
1137
+ if ((until !== undefined) || (since !== undefined)) {
1138
+ const candleDuration = this.parseTimeframe(timeframe);
1139
+ if (since !== undefined) {
1140
+ since = Math.round(since / 1000);
1141
+ request['from'] = since;
1142
+ }
1143
+ else {
1144
+ // when 'to' is defined since is mandatory
1145
+ since = (until / 100) - (maxLimit * candleDuration);
1146
+ }
1147
+ if (until !== undefined) {
1148
+ request['to'] = Math.round(until / 1000);
1149
+ }
1150
+ else {
1151
+ // when since is defined 'to' is mandatory
1152
+ let to = since + (maxLimit * candleDuration);
1153
+ const now = this.seconds();
1154
+ if (to > now) {
1155
+ to = now;
1156
+ }
1157
+ request['to'] = to;
1158
+ }
1159
+ response = await this.publicGetMdV2KlineList(this.extend(request, params));
1160
+ }
1161
+ else {
1162
+ response = await this.publicGetMdV2KlineLast(this.extend(request, params));
1163
+ }
1149
1164
  }
1150
1165
  else {
1166
+ if (since !== undefined) {
1167
+ // phemex also provides kline query with from/to, however, this interface is NOT recommended and does not work properly.
1168
+ // we do not send since param to the exchange, instead we calculate appropriate limit param
1169
+ const duration = this.parseTimeframe(timeframe) * 1000;
1170
+ const timeDelta = this.milliseconds() - since;
1171
+ limit = this.parseToInt(timeDelta / duration); // setting limit to the number of candles after since
1172
+ }
1151
1173
  response = await this.publicGetMdV2Kline(this.extend(request, params));
1152
1174
  }
1153
1175
  //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.0.108",
3
+ "version": "4.0.110",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",