ccxt 4.5.10 → 4.5.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 (79) hide show
  1. package/README.md +5 -6
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +1 -6
  4. package/dist/cjs/src/base/Exchange.js +14 -2
  5. package/dist/cjs/src/bingx.js +1 -1
  6. package/dist/cjs/src/bitfinex.js +4 -2
  7. package/dist/cjs/src/bitget.js +5 -2
  8. package/dist/cjs/src/btcmarkets.js +4 -2
  9. package/dist/cjs/src/coinbase.js +1 -0
  10. package/dist/cjs/src/deribit.js +21 -19
  11. package/dist/cjs/src/kraken.js +4 -0
  12. package/dist/cjs/src/kucoin.js +1 -1
  13. package/dist/cjs/src/latoken.js +1 -0
  14. package/dist/cjs/src/mexc.js +1 -0
  15. package/dist/cjs/src/onetrading.js +2 -1
  16. package/dist/cjs/src/phemex.js +1 -0
  17. package/dist/cjs/src/pro/bitget.js +1 -0
  18. package/dist/cjs/src/pro/htx.js +22 -3
  19. package/dist/cjs/src/pro/kraken.js +282 -458
  20. package/dist/cjs/src/pro/mexc.js +15 -10
  21. package/dist/cjs/src/probit.js +1 -1
  22. package/js/ccxt.d.ts +2 -8
  23. package/js/ccxt.js +2 -6
  24. package/js/src/abstract/coinbase.d.ts +1 -0
  25. package/js/src/abstract/coinbaseadvanced.d.ts +1 -0
  26. package/js/src/abstract/phemex.d.ts +1 -0
  27. package/js/src/base/Exchange.d.ts +5 -2
  28. package/js/src/base/Exchange.js +14 -2
  29. package/js/src/bingx.js +1 -1
  30. package/js/src/bitfinex.d.ts +1 -1
  31. package/js/src/bitfinex.js +4 -2
  32. package/js/src/bitget.d.ts +1 -1
  33. package/js/src/bitget.js +5 -2
  34. package/js/src/bithumb.d.ts +1 -1
  35. package/js/src/bitmex.d.ts +1 -1
  36. package/js/src/bitopro.d.ts +1 -1
  37. package/js/src/bitso.d.ts +1 -1
  38. package/js/src/bittrade.d.ts +1 -1
  39. package/js/src/blofin.d.ts +1 -1
  40. package/js/src/btcmarkets.d.ts +1 -1
  41. package/js/src/btcmarkets.js +4 -2
  42. package/js/src/bybit.d.ts +1 -1
  43. package/js/src/coinbase.d.ts +1 -1
  44. package/js/src/coinbase.js +1 -0
  45. package/js/src/coinex.d.ts +1 -1
  46. package/js/src/cryptocom.d.ts +1 -1
  47. package/js/src/deribit.js +21 -19
  48. package/js/src/digifinex.d.ts +1 -1
  49. package/js/src/hibachi.d.ts +1 -1
  50. package/js/src/htx.d.ts +1 -1
  51. package/js/src/hyperliquid.d.ts +1 -1
  52. package/js/src/kraken.d.ts +1 -1
  53. package/js/src/kraken.js +4 -0
  54. package/js/src/kucoin.js +1 -1
  55. package/js/src/kucoinfutures.d.ts +1 -1
  56. package/js/src/latoken.js +1 -0
  57. package/js/src/mexc.d.ts +1 -1
  58. package/js/src/mexc.js +1 -0
  59. package/js/src/oceanex.d.ts +1 -1
  60. package/js/src/okx.d.ts +1 -1
  61. package/js/src/onetrading.d.ts +1 -1
  62. package/js/src/onetrading.js +2 -1
  63. package/js/src/phemex.js +1 -0
  64. package/js/src/pro/bitget.d.ts +1 -0
  65. package/js/src/pro/bitget.js +1 -0
  66. package/js/src/pro/bitvavo.d.ts +2 -2
  67. package/js/src/pro/htx.js +22 -3
  68. package/js/src/pro/kraken.d.ts +7 -8
  69. package/js/src/pro/kraken.js +282 -458
  70. package/js/src/pro/mexc.js +15 -10
  71. package/js/src/probit.js +1 -1
  72. package/js/src/timex.d.ts +1 -1
  73. package/package.json +1 -1
  74. package/js/src/abstract/okcoin.d.ts +0 -77
  75. package/js/src/abstract/okcoin.js +0 -11
  76. package/js/src/okcoin.d.ts +0 -346
  77. package/js/src/okcoin.js +0 -3214
  78. package/js/src/pro/okcoin.d.ts +0 -91
  79. package/js/src/pro/okcoin.js +0 -763
@@ -591,55 +591,56 @@ export default class kraken extends krakenRest {
591
591
  }
592
592
  handleOHLCV(client, message, subscription) {
593
593
  //
594
- // [
595
- // 216, // channelID
596
- // [
597
- // "1574454214.962096", // Time, seconds since epoch
598
- // "1574454240.000000", // End timestamp of the interval
599
- // "0.020970", // Open price at midnight UTC
600
- // "0.020970", // Intraday high price
601
- // "0.020970", // Intraday low price
602
- // "0.020970", // Closing price at midnight UTC
603
- // "0.020970", // Volume weighted average price
604
- // "0.08636138", // Accumulated volume today
605
- // 1, // Number of trades today
606
- // ],
607
- // "ohlc-1", // Channel Name of subscription
608
- // "ETH/XBT", // Asset pair
609
- // ]
594
+ // {
595
+ // "channel": "ohlc",
596
+ // "type": "update",
597
+ // "timestamp": "2023-10-04T16:26:30.524394914Z",
598
+ // "data": [
599
+ // {
600
+ // "symbol": "MATIC/USD",
601
+ // "open": 0.5624,
602
+ // "high": 0.5628,
603
+ // "low": 0.5622,
604
+ // "close": 0.5627,
605
+ // "trades": 12,
606
+ // "volume": 30927.68066226,
607
+ // "vwap": 0.5626,
608
+ // "interval_begin": "2023-10-04T16:25:00.000000000Z",
609
+ // "interval": 5,
610
+ // "timestamp": "2023-10-04T16:30:00.000000Z"
611
+ // }
612
+ // ]
613
+ // }
610
614
  //
611
- const info = this.safeValue(subscription, 'subscription', {});
612
- const interval = this.safeInteger(info, 'interval');
613
- const name = this.safeString(info, 'name');
614
- const wsName = this.safeString(message, 3);
615
- const market = this.safeValue(this.options['marketsByWsName'], wsName);
616
- const symbol = market['symbol'];
615
+ const data = this.safeList(message, 'data', []);
616
+ const first = data[0];
617
+ const symbol = this.safeString(first, 'symbol');
618
+ const interval = this.safeInteger(first, 'interval');
617
619
  const timeframe = this.findTimeframe(interval);
618
- const duration = this.parseTimeframe(timeframe);
619
- if (timeframe !== undefined) {
620
- const candle = this.safeValue(message, 1);
621
- const messageHash = name + ':' + timeframe + ':' + wsName;
622
- let timestamp = this.safeFloat(candle, 1);
623
- timestamp -= duration;
624
- const ts = this.parseToInt(timestamp * 1000);
625
- const result = [
626
- ts,
627
- this.safeFloat(candle, 2),
628
- this.safeFloat(candle, 3),
629
- this.safeFloat(candle, 4),
630
- this.safeFloat(candle, 5),
631
- this.safeFloat(candle, 7),
620
+ const messageHash = this.getMessageHash('ohlcv', undefined, symbol);
621
+ let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
622
+ this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
623
+ if (stored === undefined) {
624
+ const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
625
+ stored = new ArrayCacheByTimestamp(limit);
626
+ this.ohlcvs[symbol][timeframe] = stored;
627
+ }
628
+ const ohlcvsLength = data.length;
629
+ for (let i = 0; i < ohlcvsLength; i++) {
630
+ const candle = data[ohlcvsLength - i - 1];
631
+ const datetime = this.safeString(candle, 'timestamp');
632
+ const timestamp = this.parse8601(datetime);
633
+ const parsed = [
634
+ timestamp,
635
+ this.safeString(candle, 'open'),
636
+ this.safeString(candle, 'high'),
637
+ this.safeString(candle, 'low'),
638
+ this.safeString(candle, 'close'),
639
+ this.safeString(candle, 'volume'),
632
640
  ];
633
- this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
634
- let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
635
- if (stored === undefined) {
636
- const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
637
- stored = new ArrayCacheByTimestamp(limit);
638
- this.ohlcvs[symbol][timeframe] = stored;
639
- }
640
- stored.append(result);
641
- client.resolve(stored, messageHash);
641
+ stored.append(parsed);
642
642
  }
643
+ client.resolve(stored, messageHash);
643
644
  }
644
645
  requestId() {
645
646
  // their support said that reqid must be an int32, not documented
@@ -647,26 +648,6 @@ export default class kraken extends krakenRest {
647
648
  this.options['reqid'] = reqid;
648
649
  return reqid;
649
650
  }
650
- async watchPublic(name, symbol, params = {}) {
651
- await this.loadMarkets();
652
- const market = this.market(symbol);
653
- const wsName = this.safeValue(market['info'], 'wsname');
654
- const messageHash = name + ':' + wsName;
655
- const url = this.urls['api']['ws']['public'];
656
- const requestId = this.requestId();
657
- const subscribe = {
658
- 'event': 'subscribe',
659
- 'reqid': requestId,
660
- 'pair': [
661
- wsName,
662
- ],
663
- 'subscription': {
664
- 'name': name,
665
- },
666
- };
667
- const request = this.deepExtend(subscribe, params);
668
- return await this.watch(url, messageHash, request, messageHash);
669
- }
670
651
  /**
671
652
  * @method
672
653
  * @name kraken#watchTicker
@@ -797,7 +778,7 @@ export default class kraken extends krakenRest {
797
778
  * @method
798
779
  * @name kraken#watchOHLCV
799
780
  * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
800
- * @see https://docs.kraken.com/api/docs/websocket-v1/ohlc
781
+ * @see https://docs.kraken.com/api/docs/websocket-v2/ohlc
801
782
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
802
783
  * @param {string} timeframe the length of time each candle represents
803
784
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
@@ -810,27 +791,24 @@ export default class kraken extends krakenRest {
810
791
  const name = 'ohlc';
811
792
  const market = this.market(symbol);
812
793
  symbol = market['symbol'];
813
- const wsName = this.safeValue(market['info'], 'wsname');
814
- const messageHash = name + ':' + timeframe + ':' + wsName;
815
- const url = this.urls['api']['ws']['public'];
794
+ const url = this.urls['api']['ws']['publicV2'];
816
795
  const requestId = this.requestId();
796
+ const messageHash = this.getMessageHash('ohlcv', undefined, symbol);
817
797
  const subscribe = {
818
- 'event': 'subscribe',
819
- 'reqid': requestId,
820
- 'pair': [
821
- wsName,
822
- ],
823
- 'subscription': {
824
- 'name': name,
798
+ 'method': 'subscribe',
799
+ 'params': {
800
+ 'channel': name,
801
+ 'symbol': [symbol],
825
802
  'interval': this.safeValue(this.timeframes, timeframe, timeframe),
826
803
  },
804
+ 'req_id': requestId,
827
805
  };
828
806
  const request = this.deepExtend(subscribe, params);
829
807
  const ohlcv = await this.watch(url, messageHash, request, messageHash);
830
808
  if (this.newUpdates) {
831
809
  limit = ohlcv.getLimit(symbol, limit);
832
810
  }
833
- return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
811
+ return this.filterBySinceLimit(ohlcv, since, limit, 'timestamp', true);
834
812
  }
835
813
  async loadMarkets(reload = false, params = {}) {
836
814
  const markets = await super.loadMarkets(reload, params);
@@ -866,16 +844,16 @@ export default class kraken extends krakenRest {
866
844
  async watchHeartbeat(params = {}) {
867
845
  await this.loadMarkets();
868
846
  const event = 'heartbeat';
869
- const url = this.urls['api']['ws']['public'];
847
+ const url = this.urls['api']['ws']['publicV2'];
870
848
  return await this.watch(url, event);
871
849
  }
872
850
  handleHeartbeat(client, message) {
873
851
  //
874
852
  // every second (approx) if no other updates are sent
875
853
  //
876
- // { "event": "heartbeat" }
854
+ // { "channel": "heartbeat" }
877
855
  //
878
- const event = this.safeString(message, 'event');
856
+ const event = this.safeString(message, 'channel');
879
857
  client.resolve(message, event);
880
858
  }
881
859
  handleOrderBook(client, message) {
@@ -1096,24 +1074,26 @@ export default class kraken extends krakenRest {
1096
1074
  async watchPrivate(name, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1097
1075
  await this.loadMarkets();
1098
1076
  const token = await this.authenticate();
1099
- const subscriptionHash = name;
1077
+ const subscriptionHash = 'executions';
1100
1078
  let messageHash = name;
1101
1079
  if (symbol !== undefined) {
1102
1080
  symbol = this.symbol(symbol);
1103
1081
  messageHash += ':' + symbol;
1104
1082
  }
1105
- const url = this.urls['api']['ws']['private'];
1083
+ const url = this.urls['api']['ws']['privateV2'];
1106
1084
  const requestId = this.requestId();
1107
1085
  const subscribe = {
1108
- 'event': 'subscribe',
1109
- 'reqid': requestId,
1110
- 'subscription': {
1111
- 'name': name,
1086
+ 'method': 'subscribe',
1087
+ 'params': {
1088
+ 'channel': 'executions',
1112
1089
  'token': token,
1113
1090
  },
1091
+ 'req_id': requestId,
1114
1092
  };
1115
- const request = this.deepExtend(subscribe, params);
1116
- const result = await this.watch(url, messageHash, request, subscriptionHash);
1093
+ if (params !== undefined) {
1094
+ subscribe['params'] = this.deepExtend(subscribe['params'], params);
1095
+ }
1096
+ const result = await this.watch(url, messageHash, subscribe, subscriptionHash);
1117
1097
  if (this.newUpdates) {
1118
1098
  limit = result.getLimit(symbol, limit);
1119
1099
  }
@@ -1123,7 +1103,7 @@ export default class kraken extends krakenRest {
1123
1103
  * @method
1124
1104
  * @name kraken#watchMyTrades
1125
1105
  * @description watches information on multiple trades made by the user
1126
- * @see https://docs.kraken.com/api/docs/websocket-v1/owntrades
1106
+ * @see https://docs.kraken.com/api/docs/websocket-v2/executions
1127
1107
  * @param {string} symbol unified market symbol of the market trades were made in
1128
1108
  * @param {int} [since] the earliest time in ms to fetch trades for
1129
1109
  * @param {int} [limit] the maximum number of trade structures to retrieve
@@ -1131,48 +1111,42 @@ export default class kraken extends krakenRest {
1131
1111
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1132
1112
  */
1133
1113
  async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1134
- return await this.watchPrivate('ownTrades', symbol, since, limit, params);
1114
+ params['snap_trades'] = true;
1115
+ return await this.watchPrivate('myTrades', symbol, since, limit, params);
1135
1116
  }
1136
1117
  handleMyTrades(client, message, subscription = undefined) {
1137
1118
  //
1138
- // [
1139
- // [
1140
- // {
1141
- // "TT5UC3-GOIRW-6AZZ6R": {
1142
- // "cost": "1493.90107",
1143
- // "fee": "3.88415",
1144
- // "margin": "0.00000",
1145
- // "ordertxid": "OTLAS3-RRHUF-NDWH5A",
1146
- // "ordertype": "market",
1147
- // "pair": "XBT/USDT",
1148
- // "postxid": "TKH2SE-M7IF5-CFI7LT",
1149
- // "price": "6851.50005",
1150
- // "time": "1586822919.335498",
1151
- // "type": "sell",
1152
- // "vol": "0.21804000"
1153
- // }
1154
- // },
1119
+ // {
1120
+ // "channel": "executions",
1121
+ // "type": "update",
1122
+ // "data": [
1155
1123
  // {
1156
- // "TIY6G4-LKLAI-Y3GD4A": {
1157
- // "cost": "22.17134",
1158
- // "fee": "0.05765",
1159
- // "margin": "0.00000",
1160
- // "ordertxid": "ODQXS7-MOLK6-ICXKAA",
1161
- // "ordertype": "market",
1162
- // "pair": "ETH/USD",
1163
- // "postxid": "TKH2SE-M7IF5-CFI7LT",
1164
- // "price": "169.97999",
1165
- // "time": "1586340530.895739",
1166
- // "type": "buy",
1167
- // "vol": "0.13043500"
1168
- // }
1169
- // },
1124
+ // "order_id": "O6NTZC-K6FRH-ATWBCK",
1125
+ // "exec_id": "T5DIUI-5N4KO-Z5BPXK",
1126
+ // "exec_type": "trade",
1127
+ // "trade_id": 8253473,
1128
+ // "symbol": "USDC/USD",
1129
+ // "side": "sell",
1130
+ // "last_qty": 15.44,
1131
+ // "last_price": 1.0002,
1132
+ // "liquidity_ind": "t",
1133
+ // "cost": 15.443088,
1134
+ // "order_userref": 0,
1135
+ // "order_status": "filled",
1136
+ // "order_type": "market",
1137
+ // "fee_usd_equiv": 0.03088618,
1138
+ // "fees": [
1139
+ // {
1140
+ // "asset": "USD",
1141
+ // "qty": 0.3458
1142
+ // }
1143
+ // ]
1144
+ // }
1170
1145
  // ],
1171
- // "ownTrades",
1172
- // { sequence: 1 }
1173
- // ]
1146
+ // "sequence": 10
1147
+ // }
1174
1148
  //
1175
- const allTrades = this.safeValue(message, 0, []);
1149
+ const allTrades = this.safeList(message, 'data', []);
1176
1150
  const allTradesLength = allTrades.length;
1177
1151
  if (allTradesLength > 0) {
1178
1152
  if (this.myTrades === undefined) {
@@ -1182,18 +1156,13 @@ export default class kraken extends krakenRest {
1182
1156
  const stored = this.myTrades;
1183
1157
  const symbols = {};
1184
1158
  for (let i = 0; i < allTrades.length; i++) {
1185
- const trades = this.safeValue(allTrades, i, {});
1186
- const ids = Object.keys(trades);
1187
- for (let j = 0; j < ids.length; j++) {
1188
- const id = ids[j];
1189
- const trade = trades[id];
1190
- const parsed = this.parseWsTrade(this.extend({ 'id': id }, trade));
1191
- stored.append(parsed);
1192
- const symbol = parsed['symbol'];
1193
- symbols[symbol] = true;
1194
- }
1159
+ const trade = this.safeDict(allTrades, i, {});
1160
+ const parsed = this.parseWsTrade(trade);
1161
+ stored.append(parsed);
1162
+ const symbol = parsed['symbol'];
1163
+ symbols[symbol] = true;
1195
1164
  }
1196
- const name = 'ownTrades';
1165
+ const name = 'myTrades';
1197
1166
  client.resolve(this.myTrades, name);
1198
1167
  const keys = Object.keys(symbols);
1199
1168
  for (let i = 0; i < keys.length; i++) {
@@ -1205,87 +1174,65 @@ export default class kraken extends krakenRest {
1205
1174
  parseWsTrade(trade, market = undefined) {
1206
1175
  //
1207
1176
  // {
1208
- // "id": "TIMIRG-WUNNE-RRJ6GT", // injected from outside
1209
- // "ordertxid": "OQRPN2-LRHFY-HIFA7D",
1210
- // "postxid": "TKH2SE-M7IF5-CFI7LT",
1211
- // "pair": "USDCUSDT",
1212
- // "time": 1586340086.457,
1213
- // "type": "sell",
1214
- // "ordertype": "market",
1215
- // "price": "0.99860000",
1216
- // "cost": "22.16892001",
1217
- // "fee": "0.04433784",
1218
- // "vol": "22.20000000",
1219
- // "margin": "0.00000000",
1220
- // "misc": ''
1221
- // }
1222
- //
1223
- // {
1224
- // "id": "TIY6G4-LKLAI-Y3GD4A",
1225
- // "cost": "22.17134",
1226
- // "fee": "0.05765",
1227
- // "margin": "0.00000",
1228
- // "ordertxid": "ODQXS7-MOLK6-ICXKAA",
1229
- // "ordertype": "market",
1230
- // "pair": "ETH/USD",
1231
- // "postxid": "TKH2SE-M7IF5-CFI7LT",
1232
- // "price": "169.97999",
1233
- // "time": "1586340530.895739",
1234
- // "type": "buy",
1235
- // "vol": "0.13043500"
1177
+ // "order_id": "O6NTZC-K6FRH-ATWBCK",
1178
+ // "exec_id": "T5DIUI-5N4KO-Z5BPXK",
1179
+ // "exec_type": "trade",
1180
+ // "trade_id": 8253473,
1181
+ // "symbol": "USDC/USD",
1182
+ // "side": "sell",
1183
+ // "last_qty": 15.44,
1184
+ // "last_price": 1.0002,
1185
+ // "liquidity_ind": "t",
1186
+ // "cost": 15.443088,
1187
+ // "order_userref": 0,
1188
+ // "order_status": "filled",
1189
+ // "order_type": "market",
1190
+ // "fee_usd_equiv": 0.03088618,
1191
+ // "fees": [
1192
+ // {
1193
+ // "asset": "USD",
1194
+ // "qty": 0.3458
1195
+ // }
1196
+ // ]
1236
1197
  // }
1237
1198
  //
1238
- const wsName = this.safeString(trade, 'pair');
1239
- market = this.safeValue(this.options['marketsByWsName'], wsName, market);
1240
- let symbol = undefined;
1241
- const orderId = this.safeString(trade, 'ordertxid');
1242
- const id = this.safeString2(trade, 'id', 'postxid');
1243
- const timestamp = this.safeTimestamp(trade, 'time');
1244
- const side = this.safeString(trade, 'type');
1245
- const type = this.safeString(trade, 'ordertype');
1246
- const price = this.safeFloat(trade, 'price');
1247
- const amount = this.safeFloat(trade, 'vol');
1248
- let cost = undefined;
1249
- let fee = undefined;
1250
- if ('fee' in trade) {
1251
- let currency = undefined;
1252
- if (market !== undefined) {
1253
- currency = market['quote'];
1254
- }
1255
- fee = {
1256
- 'cost': this.safeFloat(trade, 'fee'),
1257
- 'currency': currency,
1258
- };
1259
- }
1199
+ let symbol = this.safeString(trade, 'symbol');
1260
1200
  if (market !== undefined) {
1261
1201
  symbol = market['symbol'];
1262
1202
  }
1263
- if (price !== undefined) {
1264
- if (amount !== undefined) {
1265
- cost = price * amount;
1266
- }
1203
+ let fee = undefined;
1204
+ if ('fees' in trade) {
1205
+ const fees = this.safeList(trade, 'fees', []);
1206
+ const firstFee = this.safeDict(fees, 0, {});
1207
+ fee = {
1208
+ 'cost': this.safeNumber(firstFee, 'qty'),
1209
+ 'currency': this.safeString(firstFee, 'asset'),
1210
+ };
1267
1211
  }
1212
+ const datetime = this.safeString(trade, 'timestamp');
1213
+ const liquidityIndicator = this.safeString(trade, 'liquidity_ind');
1214
+ const takerOrMaker = (liquidityIndicator === 't') ? 'taker' : 'maker';
1268
1215
  return {
1269
- 'id': id,
1270
- 'order': orderId,
1271
1216
  'info': trade,
1272
- 'timestamp': timestamp,
1273
- 'datetime': this.iso8601(timestamp),
1217
+ 'id': this.safeString(trade, 'exec_id'),
1218
+ 'order': this.safeString(trade, 'order_id'),
1219
+ 'timestamp': this.parse8601(datetime),
1220
+ 'datetime': datetime,
1274
1221
  'symbol': symbol,
1275
- 'type': type,
1276
- 'side': side,
1277
- 'takerOrMaker': undefined,
1278
- 'price': price,
1279
- 'amount': amount,
1280
- 'cost': cost,
1222
+ 'type': this.safeString(trade, 'order_type'),
1223
+ 'side': this.safeString(trade, 'side'),
1224
+ 'takerOrMaker': takerOrMaker,
1225
+ 'price': this.safeNumber(trade, 'last_price'),
1226
+ 'amount': this.safeNumber(trade, 'last_qty'),
1227
+ 'cost': this.safeNumber(trade, 'cost'),
1281
1228
  'fee': fee,
1282
1229
  };
1283
1230
  }
1284
1231
  /**
1285
1232
  * @method
1286
1233
  * @name kraken#watchOrders
1287
- * @see https://docs.kraken.com/api/docs/websocket-v1/openorders
1288
1234
  * @description watches information on multiple orders made by the user
1235
+ * @see https://docs.kraken.com/api/docs/websocket-v2/executions
1289
1236
  * @param {string} symbol unified market symbol of the market orders were made in
1290
1237
  * @param {int} [since] the earliest time in ms to fetch orders for
1291
1238
  * @param {int} [limit] the maximum number of orde structures to retrieve
@@ -1293,87 +1240,38 @@ export default class kraken extends krakenRest {
1293
1240
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1294
1241
  */
1295
1242
  async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1296
- return await this.watchPrivate('openOrders', symbol, since, limit, params);
1243
+ params['snap_orders'] = true;
1244
+ return await this.watchPrivate('orders', symbol, since, limit, params);
1297
1245
  }
1298
1246
  handleOrders(client, message, subscription = undefined) {
1299
1247
  //
1300
- // [
1301
- // [
1302
- // {
1303
- // "OGTT3Y-C6I3P-XRI6HX": {
1304
- // "cost": "0.00000",
1305
- // "descr": {
1306
- // "close": "",
1307
- // "leverage": "0:1",
1308
- // "order": "sell 10.00345345 XBT/EUR @ limit 34.50000 with 0:1 leverage",
1309
- // "ordertype": "limit",
1310
- // "pair": "XBT/EUR",
1311
- // "price": "34.50000",
1312
- // "price2": "0.00000",
1313
- // "type": "sell"
1314
- // },
1315
- // "expiretm": "0.000000",
1316
- // "fee": "0.00000",
1317
- // "limitprice": "34.50000",
1318
- // "misc": "",
1319
- // "oflags": "fcib",
1320
- // "opentm": "0.000000",
1321
- // "price": "34.50000",
1322
- // "refid": "OKIVMP-5GVZN-Z2D2UA",
1323
- // "starttm": "0.000000",
1324
- // "status": "open",
1325
- // "stopprice": "0.000000",
1326
- // "userref": 0,
1327
- // "vol": "10.00345345",
1328
- // "vol_exec": "0.00000000"
1329
- // }
1330
- // },
1248
+ // {
1249
+ // "channel": "executions",
1250
+ // "type": "update",
1251
+ // "data": [
1331
1252
  // {
1332
- // "OGTT3Y-C6I3P-XRI6HX": {
1333
- // "cost": "0.00000",
1334
- // "descr": {
1335
- // "close": "",
1336
- // "leverage": "0:1",
1337
- // "order": "sell 0.00000010 XBT/EUR @ limit 5334.60000 with 0:1 leverage",
1338
- // "ordertype": "limit",
1339
- // "pair": "XBT/EUR",
1340
- // "price": "5334.60000",
1341
- // "price2": "0.00000",
1342
- // "type": "sell"
1343
- // },
1344
- // "expiretm": "0.000000",
1345
- // "fee": "0.00000",
1346
- // "limitprice": "5334.60000",
1347
- // "misc": "",
1348
- // "oflags": "fcib",
1349
- // "opentm": "0.000000",
1350
- // "price": "5334.60000",
1351
- // "refid": "OKIVMP-5GVZN-Z2D2UA",
1352
- // "starttm": "0.000000",
1353
- // "status": "open",
1354
- // "stopprice": "0.000000",
1355
- // "userref": 0,
1356
- // "vol": "0.00000010",
1357
- // "vol_exec": "0.00000000"
1358
- // }
1359
- // },
1360
- // ],
1361
- // "openOrders",
1362
- // { "sequence": 234 }
1363
- // ]
1364
- //
1365
- // status-change
1366
- //
1367
- // [
1368
- // [
1369
- // { "OGTT3Y-C6I3P-XRI6HX": { "status": "closed" }},
1370
- // { "OGTT3Y-C6I3P-XRI6HX": { "status": "closed" }},
1253
+ // "order_id": "OK4GJX-KSTLS-7DZZO5",
1254
+ // "order_userref": 3,
1255
+ // "symbol": "BTC/USD",
1256
+ // "order_qty": 0.005,
1257
+ // "cum_cost": 0.0,
1258
+ // "time_in_force": "GTC",
1259
+ // "exec_type": "pending_new",
1260
+ // "side": "sell",
1261
+ // "order_type": "limit",
1262
+ // "limit_price_type": "static",
1263
+ // "limit_price": 26500.0,
1264
+ // "stop_price": 0.0,
1265
+ // "order_status": "pending_new",
1266
+ // "fee_usd_equiv": 0.0,
1267
+ // "fee_ccy_pref": "fciq",
1268
+ // "timestamp": "2023-09-22T10:33:05.709950Z"
1269
+ // }
1371
1270
  // ],
1372
- // "openOrders",
1373
- // { "sequence": 59342 }
1374
- // ]
1271
+ // "sequence": 8
1272
+ // }
1375
1273
  //
1376
- const allOrders = this.safeValue(message, 0, []);
1274
+ const allOrders = this.safeList(message, 'data', []);
1377
1275
  const allOrdersLength = allOrders.length;
1378
1276
  if (allOrdersLength > 0) {
1379
1277
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
@@ -1383,43 +1281,29 @@ export default class kraken extends krakenRest {
1383
1281
  const stored = this.orders;
1384
1282
  const symbols = {};
1385
1283
  for (let i = 0; i < allOrders.length; i++) {
1386
- const orders = this.safeValue(allOrders, i, {});
1387
- const ids = Object.keys(orders);
1388
- for (let j = 0; j < ids.length; j++) {
1389
- const id = ids[j];
1390
- const order = orders[id];
1391
- const parsed = this.parseWsOrder(order);
1392
- parsed['id'] = id;
1393
- let symbol = undefined;
1284
+ const order = this.safeDict(allOrders, i, {});
1285
+ const id = this.safeString(order, 'order_id');
1286
+ const parsed = this.parseWsOrder(order);
1287
+ const symbol = this.safeString(order, 'symbol');
1288
+ const previousOrders = this.safeValue(stored.hashmap, symbol);
1289
+ const previousOrder = this.safeValue(previousOrders, id);
1290
+ let newOrder = parsed;
1291
+ if (previousOrder !== undefined) {
1292
+ const newRawOrder = this.extend(previousOrder['info'], newOrder['info']);
1293
+ newOrder = this.parseWsOrder(newRawOrder);
1294
+ }
1295
+ const length = stored.length;
1296
+ if (length === limit && (previousOrder === undefined)) {
1297
+ const first = stored[0];
1394
1298
  const symbolsByOrderId = this.safeValue(this.options, 'symbolsByOrderId', {});
1395
- if (parsed['symbol'] !== undefined) {
1396
- symbol = parsed['symbol'];
1397
- symbolsByOrderId[id] = symbol;
1398
- this.options['symbolsByOrderId'] = symbolsByOrderId;
1299
+ if (first['id'] in symbolsByOrderId) {
1300
+ delete symbolsByOrderId[first['id']];
1399
1301
  }
1400
- else {
1401
- symbol = this.safeString(symbolsByOrderId, id);
1402
- }
1403
- const previousOrders = this.safeValue(stored.hashmap, symbol);
1404
- const previousOrder = this.safeValue(previousOrders, id);
1405
- let newOrder = parsed;
1406
- if (previousOrder !== undefined) {
1407
- const newRawOrder = this.extend(previousOrder['info'], newOrder['info']);
1408
- newOrder = this.parseWsOrder(newRawOrder);
1409
- newOrder['id'] = id;
1410
- }
1411
- const length = stored.length;
1412
- if (length === limit && (previousOrder === undefined)) {
1413
- const first = stored[0];
1414
- if (first['id'] in symbolsByOrderId) {
1415
- delete symbolsByOrderId[first['id']];
1416
- }
1417
- }
1418
- stored.append(newOrder);
1419
- symbols[symbol] = true;
1420
1302
  }
1303
+ stored.append(newOrder);
1304
+ symbols[symbol] = true;
1421
1305
  }
1422
- const name = 'openOrders';
1306
+ const name = 'orders';
1423
1307
  client.resolve(this.orders, name);
1424
1308
  const keys = Object.keys(symbols);
1425
1309
  for (let i = 0; i < keys.length; i++) {
@@ -1430,122 +1314,73 @@ export default class kraken extends krakenRest {
1430
1314
  }
1431
1315
  parseWsOrder(order, market = undefined) {
1432
1316
  //
1433
- // createOrder
1434
- // {
1435
- // "avg_price": "0.00000",
1436
- // "cost": "0.00000",
1437
- // "descr": {
1438
- // "close": null,
1439
- // "leverage": null,
1440
- // "order": "sell 0.01000000 ETH/USDT @ limit 1900.00000",
1441
- // "ordertype": "limit",
1442
- // "pair": "ETH/USDT",
1443
- // "price": "1900.00000",
1444
- // "price2": "0.00000",
1445
- // "type": "sell"
1446
- // },
1447
- // "expiretm": null,
1448
- // "fee": "0.00000",
1449
- // "limitprice": "0.00000",
1450
- // "misc": '',
1451
- // "oflags": "fciq",
1452
- // "opentm": "1667522705.757622",
1453
- // "refid": null,
1454
- // "starttm": null,
1455
- // "status": "open",
1456
- // "stopprice": "0.00000",
1457
- // "timeinforce": "GTC",
1458
- // "userref": 0,
1459
- // "vol": "0.01000000",
1460
- // "vol_exec": "0.00000000"
1461
- // }
1317
+ // watchOrders
1462
1318
  //
1463
- const description = this.safeValue(order, 'descr', {});
1464
- const orderDescription = this.safeString(description, 'order');
1465
- let side = undefined;
1466
- let type = undefined;
1467
- let wsName = undefined;
1468
- let price = undefined;
1469
- let amount = undefined;
1470
- if (orderDescription !== undefined) {
1471
- const parts = orderDescription.split(' ');
1472
- side = this.safeString(parts, 0);
1473
- amount = this.safeString(parts, 1);
1474
- wsName = this.safeString(parts, 2);
1475
- type = this.safeString(parts, 4);
1476
- price = this.safeString(parts, 5);
1477
- }
1478
- side = this.safeString(description, 'type', side);
1479
- type = this.safeString(description, 'ordertype', type);
1480
- wsName = this.safeString(description, 'pair', wsName);
1481
- market = this.safeValue(this.options['marketsByWsName'], wsName, market);
1482
- let symbol = undefined;
1483
- const timestamp = this.safeTimestamp(order, 'opentm');
1484
- amount = this.safeString(order, 'vol', amount);
1485
- const filled = this.safeString(order, 'vol_exec');
1486
- let fee = undefined;
1487
- const cost = this.safeString(order, 'cost');
1488
- price = this.safeString(description, 'price', price);
1489
- if ((price === undefined) || (Precise.stringEq(price, '0.0'))) {
1490
- price = this.safeString(description, 'price2');
1491
- }
1492
- if ((price === undefined) || (Precise.stringEq(price, '0.0'))) {
1493
- price = this.safeString(order, 'price', price);
1494
- }
1495
- const average = this.safeString2(order, 'avg_price', 'price');
1496
- if (market !== undefined) {
1497
- symbol = market['symbol'];
1498
- if ('fee' in order) {
1499
- const flags = order['oflags'];
1500
- const feeCost = this.safeString(order, 'fee');
1501
- fee = {
1502
- 'cost': feeCost,
1503
- 'rate': undefined,
1504
- };
1505
- if (flags.indexOf('fciq') >= 0) {
1506
- fee['currency'] = market['quote'];
1507
- }
1508
- else if (flags.indexOf('fcib') >= 0) {
1509
- fee['currency'] = market['base'];
1510
- }
1511
- }
1512
- }
1513
- const status = this.parseOrderStatus(this.safeString(order, 'status'));
1514
- let id = this.safeString(order, 'id');
1515
- if (id === undefined) {
1516
- const txid = this.safeValue(order, 'txid');
1517
- id = this.safeString(txid, 0);
1518
- }
1519
- const clientOrderId = this.safeString(order, 'userref');
1520
- const rawTrades = this.safeValue(order, 'trades');
1521
- let trades = undefined;
1522
- if (rawTrades !== undefined) {
1523
- trades = this.parseTrades(rawTrades, market, undefined, undefined, { 'order': id });
1524
- }
1525
- const stopPrice = this.safeNumber(order, 'stopprice');
1319
+ // open order
1320
+ // {
1321
+ // "order_id": "OK4GJX-KSTLS-7DZZO5",
1322
+ // "order_userref": 3,
1323
+ // "symbol": "BTC/USD",
1324
+ // "order_qty": 0.005,
1325
+ // "cum_cost": 0.0,
1326
+ // "time_in_force": "GTC",
1327
+ // "exec_type": "pending_new",
1328
+ // "side": "sell",
1329
+ // "order_type": "limit",
1330
+ // "limit_price_type": "static",
1331
+ // "limit_price": 26500.0,
1332
+ // "stop_price": 0.0,
1333
+ // "order_status": "pending_new",
1334
+ // "fee_usd_equiv": 0.0,
1335
+ // "fee_ccy_pref": "fciq",
1336
+ // "timestamp": "2023-09-22T10:33:05.709950Z"
1337
+ // }
1338
+ //
1339
+ // canceled order
1340
+ //
1341
+ // {
1342
+ // "timestamp": "2025-10-11T15:11:47.695226Z",
1343
+ // "order_status": "canceled",
1344
+ // "exec_type": "canceled",
1345
+ // "order_userref": 0,
1346
+ // "order_id": "OGAB7Y-BKX5F-PTK5RW",
1347
+ // "cum_qty": 0,
1348
+ // "cum_cost": 0,
1349
+ // "fee_usd_equiv": 0,
1350
+ // "avg_price": 0,
1351
+ // "cancel_reason": "User requested",
1352
+ // "reason": "User requested"
1353
+ // }
1354
+ //
1355
+ const fee = {
1356
+ 'cost': this.safeString(order, 'fee_usd_equiv'),
1357
+ 'currency': 'USD',
1358
+ };
1359
+ const stopPrice = this.safeString(order, 'stop_price');
1360
+ const datetime = this.safeString(order, 'timestamp');
1526
1361
  return this.safeOrder({
1527
- 'id': id,
1528
- 'clientOrderId': clientOrderId,
1362
+ 'id': this.safeString(order, 'order_id'),
1363
+ 'clientOrderId': this.safeString(order, 'order_userref'),
1529
1364
  'info': order,
1530
- 'timestamp': timestamp,
1531
- 'datetime': this.iso8601(timestamp),
1365
+ 'timestamp': this.parse8601(datetime),
1366
+ 'datetime': datetime,
1532
1367
  'lastTradeTimestamp': undefined,
1533
- 'status': status,
1534
- 'symbol': symbol,
1535
- 'type': type,
1536
- 'timeInForce': undefined,
1368
+ 'status': this.parseOrderStatus(this.safeString(order, 'order_status')),
1369
+ 'symbol': this.safeString(order, 'symbol'),
1370
+ 'type': this.safeString(order, 'order_type'),
1371
+ 'timeInForce': this.safeString(order, 'time_in_force'),
1537
1372
  'postOnly': undefined,
1538
- 'side': side,
1539
- 'price': price,
1373
+ 'side': this.safeString(order, 'side'),
1374
+ 'price': this.safeString(order, 'limit_price'),
1540
1375
  'stopPrice': stopPrice,
1541
1376
  'triggerPrice': stopPrice,
1542
- 'cost': cost,
1543
- 'amount': amount,
1544
- 'filled': filled,
1545
- 'average': average,
1377
+ 'cost': this.safeString(order, 'cum_cost'),
1378
+ 'amount': this.safeString2(order, 'order_qty', 'cum_qty'),
1379
+ 'filled': undefined,
1380
+ 'average': this.safeString(order, 'avg_price'),
1546
1381
  'remaining': undefined,
1547
1382
  'fee': fee,
1548
- 'trades': trades,
1383
+ 'trades': undefined,
1549
1384
  });
1550
1385
  }
1551
1386
  async watchMultiHelper(unifiedName, channelName, symbols = undefined, subscriptionArgs = undefined, params = {}) {
@@ -1728,55 +1563,44 @@ export default class kraken extends krakenRest {
1728
1563
  return true;
1729
1564
  }
1730
1565
  handleMessage(client, message) {
1731
- if (Array.isArray(message)) {
1732
- const channelId = this.safeString(message, 0);
1733
- const subscription = this.safeValue(client.subscriptions, channelId, {});
1734
- const info = this.safeValue(subscription, 'subscription', {});
1735
- const messageLength = message.length;
1736
- const channelName = this.safeString(message, messageLength - 2);
1737
- const name = this.safeString(info, 'name');
1566
+ let channel = this.safeString(message, 'channel');
1567
+ if (channel !== undefined) {
1568
+ if (channel === 'executions') {
1569
+ const data = this.safeList(message, 'data', []);
1570
+ const first = this.safeDict(data, 0, {});
1571
+ const execType = this.safeString(first, 'exec_type');
1572
+ channel = (execType === 'trade') ? 'myTrades' : 'orders';
1573
+ }
1738
1574
  const methods = {
1739
- // public
1575
+ 'balances': this.handleBalance,
1576
+ 'book': this.handleOrderBook,
1740
1577
  'ohlc': this.handleOHLCV,
1578
+ 'ticker': this.handleTicker,
1579
+ 'trade': this.handleTrades,
1741
1580
  // private
1742
- 'openOrders': this.handleOrders,
1743
- 'ownTrades': this.handleMyTrades,
1581
+ 'myTrades': this.handleMyTrades,
1582
+ 'orders': this.handleOrders,
1744
1583
  };
1745
- const method = this.safeValue2(methods, name, channelName);
1584
+ const method = this.safeValue(methods, channel);
1746
1585
  if (method !== undefined) {
1747
- method.call(this, client, message, subscription);
1586
+ method.call(this, client, message);
1748
1587
  }
1749
1588
  }
1750
- else {
1751
- const channel = this.safeString(message, 'channel');
1752
- if (channel !== undefined) {
1753
- const methods = {
1754
- 'balances': this.handleBalance,
1755
- 'book': this.handleOrderBook,
1756
- 'ticker': this.handleTicker,
1757
- 'trade': this.handleTrades,
1758
- };
1759
- const method = this.safeValue(methods, channel);
1760
- if (method !== undefined) {
1761
- method.call(this, client, message);
1762
- }
1763
- }
1764
- if (this.handleErrorMessage(client, message)) {
1765
- const event = this.safeString2(message, 'event', 'method');
1766
- const methods = {
1767
- 'heartbeat': this.handleHeartbeat,
1768
- 'systemStatus': this.handleSystemStatus,
1769
- 'subscriptionStatus': this.handleSubscriptionStatus,
1770
- 'add_order': this.handleCreateEditOrder,
1771
- 'amend_order': this.handleCreateEditOrder,
1772
- 'cancel_order': this.handleCancelOrder,
1773
- 'cancel_all': this.handleCancelAllOrders,
1774
- 'pong': this.handlePong,
1775
- };
1776
- const method = this.safeValue(methods, event);
1777
- if (method !== undefined) {
1778
- method.call(this, client, message);
1779
- }
1589
+ if (this.handleErrorMessage(client, message)) {
1590
+ const event = this.safeString2(message, 'event', 'method');
1591
+ const methods = {
1592
+ 'heartbeat': this.handleHeartbeat,
1593
+ 'systemStatus': this.handleSystemStatus,
1594
+ 'subscriptionStatus': this.handleSubscriptionStatus,
1595
+ 'add_order': this.handleCreateEditOrder,
1596
+ 'amend_order': this.handleCreateEditOrder,
1597
+ 'cancel_order': this.handleCancelOrder,
1598
+ 'cancel_all': this.handleCancelAllOrders,
1599
+ 'pong': this.handlePong,
1600
+ };
1601
+ const method = this.safeValue(methods, event);
1602
+ if (method !== undefined) {
1603
+ method.call(this, client, message);
1780
1604
  }
1781
1605
  }
1782
1606
  }