ccxt 4.1.37 → 4.1.39

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/huobi.js CHANGED
@@ -4823,6 +4823,7 @@ export default class huobi extends Exchange {
4823
4823
  * @param {string} [params.offset] *contract only* 'open', 'close', or 'both', required in hedge mode
4824
4824
  * @param {bool} [params.postOnly] *contract only* true or false
4825
4825
  * @param {int} [params.leverRate] *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
4826
+ * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
4826
4827
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
4827
4828
  */
4828
4829
  await this.loadMarkets();
@@ -4895,6 +4896,13 @@ export default class huobi extends Exchange {
4895
4896
  if (postOnly) {
4896
4897
  orderType = 'limit-maker';
4897
4898
  }
4899
+ const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
4900
+ if (timeInForce === 'FOK') {
4901
+ orderType = orderType + '-fok';
4902
+ }
4903
+ else if (timeInForce === 'IOC') {
4904
+ orderType = 'ioc';
4905
+ }
4898
4906
  request['type'] = side + '-' + orderType;
4899
4907
  const clientOrderId = this.safeString2(params, 'clientOrderId', 'client-order-id'); // must be 64 chars max and unique within 24 hours
4900
4908
  if (clientOrderId === undefined) {
@@ -4942,7 +4950,7 @@ export default class huobi extends Exchange {
4942
4950
  if (orderType in limitOrderTypes) {
4943
4951
  request['price'] = this.priceToPrecision(symbol, price);
4944
4952
  }
4945
- params = this.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator']);
4953
+ params = this.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce']);
4946
4954
  const response = await this.spotPrivatePostV1OrderOrdersPlace(this.extend(request, params));
4947
4955
  //
4948
4956
  // spot
@@ -4987,6 +4995,7 @@ export default class huobi extends Exchange {
4987
4995
  * @param {float} amount how much of currency you want to trade in units of base currency
4988
4996
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4989
4997
  * @param {object} params extra parameters specific to the huobi api endpoint
4998
+ * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
4990
4999
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
4991
5000
  */
4992
5001
  const market = this.market(symbol);
@@ -5000,6 +5009,13 @@ export default class huobi extends Exchange {
5000
5009
  if (postOnly) {
5001
5010
  type = 'post_only';
5002
5011
  }
5012
+ const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
5013
+ if (timeInForce === 'FOK') {
5014
+ type = 'fok';
5015
+ }
5016
+ else if (timeInForce === 'IOC') {
5017
+ type = 'ioc';
5018
+ }
5003
5019
  const triggerPrice = this.safeNumber2(params, 'stopPrice', 'trigger_price');
5004
5020
  const stopLossTriggerPrice = this.safeNumber2(params, 'stopLossPrice', 'sl_trigger_price');
5005
5021
  const takeProfitTriggerPrice = this.safeNumber2(params, 'takeProfitPrice', 'tp_trigger_price');
@@ -5052,7 +5068,7 @@ export default class huobi extends Exchange {
5052
5068
  request['lever_rate'] = leverRate;
5053
5069
  request['order_price_type'] = type;
5054
5070
  }
5055
- params = this.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate']);
5071
+ params = this.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce']);
5056
5072
  const broker = this.safeValue(this.options, 'broker', {});
5057
5073
  const brokerId = this.safeString(broker, 'id');
5058
5074
  request['channel_code'] = brokerId;
@@ -96,6 +96,7 @@ export default class krakenfutures extends Exchange {
96
96
  'api': {
97
97
  'public': {
98
98
  'get': [
99
+ 'feeschedules',
99
100
  'instruments',
100
101
  'orderbook',
101
102
  'tickers',
@@ -105,6 +106,7 @@ export default class krakenfutures extends Exchange {
105
106
  },
106
107
  'private': {
107
108
  'get': [
109
+ 'feeschedules/volumes',
108
110
  'openpositions',
109
111
  'notifications',
110
112
  'accounts',
@@ -145,11 +147,6 @@ export default class krakenfutures extends Exchange {
145
147
  'market/{symbol}/executions',
146
148
  ],
147
149
  },
148
- 'feeschedules': {
149
- 'get': [
150
- 'volumes',
151
- ],
152
- },
153
150
  },
154
151
  'fees': {
155
152
  'trading': {
package/js/src/mexc.js CHANGED
@@ -2701,16 +2701,16 @@ export default class mexc extends Exchange {
2701
2701
  await this.loadMarkets();
2702
2702
  const request = {};
2703
2703
  let market = undefined;
2704
+ let marketType = undefined;
2704
2705
  if (symbol !== undefined) {
2705
2706
  market = this.market(symbol);
2706
- request['symbol'] = market['id'];
2707
2707
  }
2708
- let marketType = undefined;
2709
2708
  [marketType, params] = this.handleMarketTypeAndParams('fetchOpenOrders', market, params);
2710
2709
  if (marketType === 'spot') {
2711
2710
  if (symbol === undefined) {
2712
2711
  throw new ArgumentsRequired(this.id + ' fetchOpenOrders() requires a symbol argument for spot market');
2713
2712
  }
2713
+ request['symbol'] = market['id'];
2714
2714
  let method = 'spotPrivateGetOpenOrders';
2715
2715
  const [marginMode, query] = this.handleMarginModeAndParams('fetchOpenOrders', params);
2716
2716
  if (marginMode !== undefined) {
@@ -2807,7 +2807,6 @@ export default class mexc extends Exchange {
2807
2807
  let market = undefined;
2808
2808
  if (symbol !== undefined) {
2809
2809
  market = this.market(symbol);
2810
- request['symbol'] = market['id'];
2811
2810
  }
2812
2811
  const [marketType] = this.handleMarketTypeAndParams('fetchOrdersByState', market, params);
2813
2812
  if (marketType === 'spot') {
package/js/src/phemex.js CHANGED
@@ -1983,6 +1983,9 @@ export default class phemex extends Exchange {
1983
1983
  'Filled': 'closed',
1984
1984
  'Canceled': 'canceled',
1985
1985
  '1': 'open',
1986
+ '2': 'canceled',
1987
+ '3': 'closed',
1988
+ '4': 'canceled',
1986
1989
  '5': 'open',
1987
1990
  '6': 'open',
1988
1991
  '7': 'closed',
@@ -10,6 +10,9 @@ import { Precise } from '../base/Precise.js';
10
10
  import { ExchangeError, ArgumentsRequired, BadRequest } from '../base/errors.js';
11
11
  import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
12
12
  import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
13
+ import { rsa } from '../base/functions/rsa.js';
14
+ import { eddsa } from '../base/functions/crypto.js';
15
+ import { ed25519 } from '../static_dependencies/noble-curves/ed25519.js';
13
16
  // -----------------------------------------------------------------------------
14
17
  export default class binance extends binanceRest {
15
18
  describe() {
@@ -1216,7 +1219,20 @@ export default class binance extends binanceRest {
1216
1219
  params['recvWindow'] = recvWindow;
1217
1220
  }
1218
1221
  extendedParams = this.keysort(extendedParams);
1219
- extendedParams['signature'] = this.hmac(this.encode(this.urlencode(extendedParams)), this.encode(this.secret), sha256);
1222
+ const query = this.urlencode(extendedParams);
1223
+ let signature = undefined;
1224
+ if (this.secret.indexOf('PRIVATE KEY') > -1) {
1225
+ if (this.secret.length > 120) {
1226
+ signature = rsa(query, this.secret, sha256);
1227
+ }
1228
+ else {
1229
+ signature = eddsa(this.encode(query), this.secret, ed25519);
1230
+ }
1231
+ }
1232
+ else {
1233
+ signature = this.hmac(this.encode(query), this.encode(this.secret), sha256);
1234
+ }
1235
+ extendedParams['signature'] = signature;
1220
1236
  return extendedParams;
1221
1237
  }
1222
1238
  async authenticate(params = {}) {
@@ -2535,6 +2551,15 @@ export default class binance extends binanceRest {
2535
2551
  }
2536
2552
  }
2537
2553
  handleWsError(client, message) {
2554
+ //
2555
+ // {
2556
+ // "error": {
2557
+ // "code": 2,
2558
+ // "msg": "Invalid request: invalid stream"
2559
+ // },
2560
+ // "id": 1
2561
+ // }
2562
+ //
2538
2563
  const id = this.safeString(message, 'id');
2539
2564
  let rejected = false;
2540
2565
  const error = this.safeValue(message, 'error', {});
@@ -2545,7 +2570,17 @@ export default class binance extends binanceRest {
2545
2570
  }
2546
2571
  catch (e) {
2547
2572
  rejected = true;
2573
+ // private endpoint uses id as messageHash
2548
2574
  client.reject(e, id);
2575
+ // public endpoint stores messageHash in subscriptios
2576
+ const subscriptionKeys = Object.keys(client.subscriptions);
2577
+ for (let i = 0; i < subscriptionKeys.length; i++) {
2578
+ const subscriptionHash = subscriptionKeys[i];
2579
+ const subscriptionId = this.safeString(client.subscriptions[subscriptionHash], 'id');
2580
+ if (id === subscriptionId) {
2581
+ client.reject(e, subscriptionHash);
2582
+ }
2583
+ }
2549
2584
  }
2550
2585
  if (!rejected) {
2551
2586
  client.reject(message, id);
@@ -2558,7 +2593,8 @@ export default class binance extends binanceRest {
2558
2593
  handleMessage(client, message) {
2559
2594
  // handle WebSocketAPI
2560
2595
  const status = this.safeString(message, 'status');
2561
- if (status !== undefined && status !== '200') {
2596
+ const error = this.safeValue(message, 'error');
2597
+ if ((error !== undefined) || (status !== undefined && status !== '200')) {
2562
2598
  return this.handleWsError(client, message);
2563
2599
  }
2564
2600
  const id = this.safeString(message, 'id');
@@ -757,6 +757,9 @@ export default class bitget extends bitgetRest {
757
757
  /**
758
758
  * @method
759
759
  * @name bitget#watchOrders
760
+ * @see https://bitgetlimited.github.io/apidoc/en/spot/#order-channel
761
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#order-channel
762
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#plan-order-channel
760
763
  * @description watches information on multiple orders made by the user
761
764
  * @param {string} symbol unified market symbol of the market orders were made in
762
765
  * @param {int} [since] the earliest time in ms to fetch orders for
@@ -767,7 +770,9 @@ export default class bitget extends bitgetRest {
767
770
  await this.loadMarkets();
768
771
  let market = undefined;
769
772
  let marketId = undefined;
770
- let messageHash = 'order';
773
+ const isStop = this.safeValue(params, 'stop', false);
774
+ params = this.omit(params, 'stop');
775
+ let messageHash = (isStop) ? 'triggerOrder' : 'order';
771
776
  let subscriptionHash = 'order:trades';
772
777
  if (symbol !== undefined) {
773
778
  market = this.market(symbol);
@@ -775,8 +780,6 @@ export default class bitget extends bitgetRest {
775
780
  marketId = market['id'];
776
781
  messageHash = messageHash + ':' + symbol;
777
782
  }
778
- const isStop = this.safeValue(params, 'stop', false);
779
- params = this.omit(params, 'stop');
780
783
  let type = undefined;
781
784
  [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
782
785
  if ((type === 'spot') && (symbol === undefined)) {
@@ -799,6 +802,9 @@ export default class bitget extends bitgetRest {
799
802
  instType = 'SUMCBL';
800
803
  }
801
804
  }
805
+ if (isStop) {
806
+ subscriptionHash = subscriptionHash + ':stop'; // we don't want to re-use the same subscription hash for stop orders
807
+ }
802
808
  const instId = (type === 'spot') ? marketId : 'default'; // different from other streams here the 'rest' id is required for spot markets, contract markets require default here
803
809
  const channel = isStop ? 'ordersAlgo' : 'orders';
804
810
  const args = {
@@ -840,7 +846,42 @@ export default class bitget extends bitgetRest {
840
846
  // ]
841
847
  // }
842
848
  //
849
+ // {
850
+ // action: 'snapshot',
851
+ // arg: { instType: 'umcbl', channel: 'ordersAlgo', instId: 'default' },
852
+ // data: [
853
+ // {
854
+ // actualPx: '55.000000000',
855
+ // actualSz: '0.000000000',
856
+ // cOid: '1104372235724890112',
857
+ // cTime: '1699028779917',
858
+ // eps: 'web',
859
+ // hM: 'double_hold',
860
+ // id: '1104372235724890113',
861
+ // instId: 'BTCUSDT_UMCBL',
862
+ // key: '1104372235724890113',
863
+ // ordPx: '55.000000000',
864
+ // ordType: 'limit',
865
+ // planType: 'pl',
866
+ // posSide: 'long',
867
+ // side: 'buy',
868
+ // state: 'not_trigger',
869
+ // sz: '3.557000000',
870
+ // tS: 'open_long',
871
+ // tgtCcy: 'USDT',
872
+ // triggerPx: '55.000000000',
873
+ // triggerPxType: 'last',
874
+ // triggerTime: '1699028779917',
875
+ // uTime: '1699028779917',
876
+ // userId: '3704614084',
877
+ // version: 1104372235586478100
878
+ // }
879
+ // ],
880
+ // ts: 1699028780327
881
+ // }
882
+ //
843
883
  const arg = this.safeValue(message, 'arg', {});
884
+ const channel = this.safeString(arg, 'channel');
844
885
  const instType = this.safeString(arg, 'instType');
845
886
  const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
846
887
  const isContractUpdate = (!sandboxMode) ? (instType === 'umcbl') : (instType === 'sumcbl');
@@ -848,8 +889,10 @@ export default class bitget extends bitgetRest {
848
889
  if (this.orders === undefined) {
849
890
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
850
891
  this.orders = new ArrayCacheBySymbolById(limit);
892
+ this.triggerOrders = new ArrayCacheBySymbolById(limit);
851
893
  }
852
- const stored = this.orders;
894
+ const stored = (channel === 'ordersAlgo') ? this.triggerOrders : this.orders;
895
+ const messageHash = (channel === 'ordersAlgo') ? 'triggerOrder' : 'order';
853
896
  const marketSymbols = {};
854
897
  for (let i = 0; i < data.length; i++) {
855
898
  const order = data[i];
@@ -866,10 +909,10 @@ export default class bitget extends bitgetRest {
866
909
  const keys = Object.keys(marketSymbols);
867
910
  for (let i = 0; i < keys.length; i++) {
868
911
  const symbol = keys[i];
869
- const messageHash = 'order:' + symbol;
870
- client.resolve(stored, messageHash);
912
+ const innerMessageHash = messageHash + ':' + symbol;
913
+ client.resolve(stored, innerMessageHash);
871
914
  }
872
- client.resolve(stored, 'order');
915
+ client.resolve(stored, messageHash);
873
916
  }
874
917
  parseWsOrder(order, market = undefined) {
875
918
  //
package/js/src/wazirx.js CHANGED
@@ -29,14 +29,23 @@ export default class wazirx extends Exchange {
29
29
  'swap': false,
30
30
  'future': false,
31
31
  'option': false,
32
+ 'addMargin': false,
33
+ 'borrowMargin': false,
32
34
  'cancelAllOrders': true,
33
35
  'cancelOrder': true,
34
36
  'createOrder': true,
37
+ 'createReduceOnlyOrder': false,
35
38
  'createStopLimitOrder': true,
36
39
  'createStopMarketOrder': true,
37
40
  'createStopOrder': true,
38
41
  'fetchBalance': true,
39
42
  'fetchBidsAsks': false,
43
+ 'fetchBorrowInterest': false,
44
+ 'fetchBorrowRate': false,
45
+ 'fetchBorrowRateHistories': false,
46
+ 'fetchBorrowRateHistory': false,
47
+ 'fetchBorrowRates': false,
48
+ 'fetchBorrowRatesPerSymbol': false,
40
49
  'fetchClosedOrders': false,
41
50
  'fetchCurrencies': false,
42
51
  'fetchDepositAddress': false,
@@ -48,7 +57,11 @@ export default class wazirx extends Exchange {
48
57
  'fetchFundingRateHistory': false,
49
58
  'fetchFundingRates': false,
50
59
  'fetchIndexOHLCV': false,
60
+ 'fetchIsolatedPositions': false,
61
+ 'fetchLeverage': false,
62
+ 'fetchLeverageTiers': false,
51
63
  'fetchMarginMode': false,
64
+ 'fetchMarketLeverageTiers': false,
52
65
  'fetchMarkets': true,
53
66
  'fetchMarkOHLCV': false,
54
67
  'fetchMyTrades': false,
@@ -58,7 +71,10 @@ export default class wazirx extends Exchange {
58
71
  'fetchOrder': false,
59
72
  'fetchOrderBook': true,
60
73
  'fetchOrders': true,
74
+ 'fetchPosition': false,
61
75
  'fetchPositionMode': false,
76
+ 'fetchPositions': false,
77
+ 'fetchPositionsRisk': false,
62
78
  'fetchPremiumIndexOHLCV': false,
63
79
  'fetchStatus': true,
64
80
  'fetchTicker': true,
@@ -71,6 +87,12 @@ export default class wazirx extends Exchange {
71
87
  'fetchTransactions': false,
72
88
  'fetchTransfers': false,
73
89
  'fetchWithdrawals': false,
90
+ 'reduceMargin': false,
91
+ 'repayMargin': false,
92
+ 'setLeverage': false,
93
+ 'setMargin': false,
94
+ 'setMarginMode': false,
95
+ 'setPositionMode': false,
74
96
  'transfer': false,
75
97
  'withdraw': false,
76
98
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.1.37",
3
+ "version": "4.1.39",
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",
@@ -116,7 +116,7 @@
116
116
  "as-table": "1.0.37",
117
117
  "asciichart": "^1.5.25",
118
118
  "assert": "^2.0.0",
119
- "ast-transpiler": "^0.0.24",
119
+ "ast-transpiler": "^0.0.25",
120
120
  "docsify": "^4.13.1",
121
121
  "eslint": "^8.8.0",
122
122
  "eslint-config-airbnb-base": "15.0.0",
package/skip-tests.json CHANGED
@@ -1074,7 +1074,12 @@
1074
1074
  },
1075
1075
  "kuna": {
1076
1076
  "httpsProxy": "http://51.83.140.52:11230",
1077
- "skipPhpAsync": true
1077
+ "skipPhpAsync": true,
1078
+ "skipMethods": {
1079
+ "loadMarkets": {
1080
+ "active":"is undefined"
1081
+ }
1082
+ }
1078
1083
  },
1079
1084
  "kucoin": {
1080
1085
  "skipWs": true,