ccxt 4.4.62 → 4.4.64

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/gate.js CHANGED
@@ -8,7 +8,7 @@
8
8
  import Exchange from './abstract/gate.js';
9
9
  import { Precise } from './base/Precise.js';
10
10
  import { TICK_SIZE } from './base/functions/number.js';
11
- import { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled, OrderImmediatelyFillable, BadResponse } from './base/errors.js';
11
+ import { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled, OrderImmediatelyFillable } from './base/errors.js';
12
12
  import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
13
13
  /**
14
14
  * @class gate
@@ -1829,103 +1829,83 @@ export default class gate extends Exchange {
1829
1829
  }
1830
1830
  const response = await this.publicSpotGetCurrencies(params);
1831
1831
  //
1832
- // {
1833
- // "currency": "BCN",
1834
- // "delisted": false,
1835
- // "withdraw_disabled": true,
1836
- // "withdraw_delayed": false,
1837
- // "deposit_disabled": true,
1838
- // "trade_disabled": false
1839
- // }
1840
- //
1841
- // {
1842
- // "currency":"USDT_ETH",
1843
- // "delisted":false,
1844
- // "withdraw_disabled":false,
1845
- // "withdraw_delayed":false,
1846
- // "deposit_disabled":false,
1847
- // "trade_disabled":false,
1848
- // "chain":"ETH"
1849
- // }
1850
- //
1832
+ // [
1833
+ // {
1834
+ // "currency": "USDT_ETH",
1835
+ // "name": "Tether",
1836
+ // "delisted": false,
1837
+ // "withdraw_disabled": false,
1838
+ // "withdraw_delayed": false,
1839
+ // "deposit_disabled": false,
1840
+ // "trade_disabled": true,
1841
+ // "chain": "ETH"
1842
+ // },
1843
+ // ]
1844
+ //
1845
+ const indexedCurrencies = this.indexBy(response, 'currency');
1851
1846
  const result = {};
1852
1847
  for (let i = 0; i < response.length; i++) {
1853
1848
  const entry = response[i];
1854
1849
  const currencyId = this.safeString(entry, 'currency');
1855
- const currencyIdLower = this.safeStringLower(entry, 'currency');
1856
1850
  const parts = currencyId.split('_');
1857
- const currency = parts[0];
1858
- const code = this.safeCurrencyCode(currency);
1859
- const networkId = this.safeString(entry, 'chain');
1860
- let networkCode = undefined;
1861
- if (networkId !== undefined) {
1862
- networkCode = this.networkIdToCode(networkId, code);
1851
+ const partFirst = this.safeString(parts, 0);
1852
+ // if there's an underscore then the second part is always the chain name (except the _OLD suffix)
1853
+ const currencyName = currencyId.endsWith('_OLD') ? currencyId : partFirst;
1854
+ const withdrawEnabled = !this.safeBool(entry, 'withdraw_disabled');
1855
+ const depositEnabled = !this.safeBool(entry, 'deposit_disabled');
1856
+ const tradeDisabled = !this.safeBool(entry, 'trade_disabled');
1857
+ const precision = this.parseNumber('0.0001'); // temporary safe default, because no value provided from API
1858
+ const code = this.safeCurrencyCode(currencyName);
1859
+ // check leveraged tokens (e.g. BTC3S, ETH5L)
1860
+ let isLeveragedToken = false;
1861
+ if (currencyId.endsWith('3S') || currencyId.endsWith('3L') || currencyId.endsWith('5S') || currencyId.endsWith('5L')) {
1862
+ const realCurrencyId = currencyId.slice(0, -2);
1863
+ if (realCurrencyId in indexedCurrencies) {
1864
+ isLeveragedToken = true;
1865
+ }
1863
1866
  }
1864
- const delisted = this.safeValue(entry, 'delisted');
1865
- const withdrawDisabled = this.safeBool(entry, 'withdraw_disabled', false);
1866
- const depositDisabled = this.safeBool(entry, 'deposit_disabled', false);
1867
- const tradeDisabled = this.safeBool(entry, 'trade_disabled', false);
1868
- const withdrawEnabled = !withdrawDisabled;
1869
- const depositEnabled = !depositDisabled;
1870
- const tradeEnabled = !tradeDisabled;
1871
- const listed = !delisted;
1872
- const active = listed && tradeEnabled && withdrawEnabled && depositEnabled;
1873
- if (this.safeValue(result, code) === undefined) {
1867
+ const type = isLeveragedToken ? 'leveraged' : 'crypto';
1868
+ // some networks are null, they are mostly obsolete & unsupported dead tokens, so we can default their networkId to their tokenname
1869
+ const networkId = this.safeString(entry, 'chain', currencyId);
1870
+ const networkCode = this.networkIdToCode(networkId, code);
1871
+ const networkEntry = {
1872
+ 'info': entry,
1873
+ 'id': networkId,
1874
+ 'network': networkCode,
1875
+ 'limits': {
1876
+ 'deposit': {
1877
+ 'min': undefined,
1878
+ 'max': undefined,
1879
+ },
1880
+ 'withdraw': {
1881
+ 'min': undefined,
1882
+ 'max': undefined,
1883
+ },
1884
+ },
1885
+ 'active': !tradeDisabled,
1886
+ 'deposit': depositEnabled,
1887
+ 'withdraw': withdrawEnabled,
1888
+ 'fee': undefined,
1889
+ 'precision': precision,
1890
+ };
1891
+ // check if first entry for the specific currency
1892
+ if (!(code in result)) {
1874
1893
  result[code] = {
1875
- 'id': currency,
1894
+ 'id': currencyName,
1895
+ 'lowerCaseId': currencyName.toLowerCase(),
1876
1896
  'code': code,
1877
- 'info': undefined,
1878
- 'name': undefined,
1879
- 'active': active,
1880
- 'deposit': depositEnabled,
1881
- 'withdraw': withdrawEnabled,
1882
- 'fee': undefined,
1883
- 'fees': [],
1884
- 'precision': this.parseNumber('1e-4'),
1897
+ 'type': type,
1898
+ 'precision': precision,
1885
1899
  'limits': this.limits,
1886
1900
  'networks': {},
1901
+ 'info': [], // will be filled below
1887
1902
  };
1888
1903
  }
1889
- let depositAvailable = this.safeValue(result[code], 'deposit');
1890
- depositAvailable = (depositEnabled) ? depositEnabled : depositAvailable;
1891
- let withdrawAvailable = this.safeValue(result[code], 'withdraw');
1892
- withdrawAvailable = (withdrawEnabled) ? withdrawEnabled : withdrawAvailable;
1893
- const networks = this.safeValue(result[code], 'networks', {});
1894
- if (networkCode !== undefined) {
1895
- networks[networkCode] = {
1896
- 'info': entry,
1897
- 'id': networkId,
1898
- 'network': networkCode,
1899
- 'currencyId': currencyId,
1900
- 'lowerCaseCurrencyId': currencyIdLower,
1901
- 'deposit': depositEnabled,
1902
- 'withdraw': withdrawEnabled,
1903
- 'active': active,
1904
- 'fee': undefined,
1905
- 'precision': this.parseNumber('1e-4'),
1906
- 'limits': {
1907
- 'amount': {
1908
- 'min': undefined,
1909
- 'max': undefined,
1910
- },
1911
- 'withdraw': {
1912
- 'min': undefined,
1913
- 'max': undefined,
1914
- },
1915
- 'deposit': {
1916
- 'min': undefined,
1917
- 'max': undefined,
1918
- },
1919
- },
1920
- };
1921
- }
1922
- result[code]['networks'] = networks;
1923
- const info = this.safeValue(result[code], 'info', []);
1904
+ result[code]['networks'][networkCode] = networkEntry;
1905
+ const info = this.safeList(result[code], 'info', []);
1924
1906
  info.push(entry);
1925
1907
  result[code]['info'] = info;
1926
- result[code]['active'] = depositAvailable && withdrawAvailable;
1927
- result[code]['deposit'] = depositAvailable;
1928
- result[code]['withdraw'] = withdrawAvailable;
1908
+ result[code] = this.safeCurrencyStructure(result[code]); // this is needed after adding network entry
1929
1909
  }
1930
1910
  return result;
1931
1911
  }
@@ -2174,6 +2154,29 @@ export default class gate extends Exchange {
2174
2154
  }
2175
2155
  return result;
2176
2156
  }
2157
+ /**
2158
+ * @method
2159
+ * @name gate#fetchDepositAddressesByNetwork
2160
+ * @description fetch a dictionary of addresses for a currency, indexed by network
2161
+ * @param {string} code unified currency code of the currency for the deposit address
2162
+ * @param {object} [params] extra parameters specific to the api endpoint
2163
+ * @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network
2164
+ */
2165
+ async fetchDepositAddressesByNetwork(code, params = {}) {
2166
+ await this.loadMarkets();
2167
+ let currency = this.currency(code);
2168
+ const request = {
2169
+ 'currency': currency['id'],
2170
+ };
2171
+ const response = await this.privateWalletGetDepositAddress(this.extend(request, params));
2172
+ const chains = this.safeValue(response, 'multichain_addresses', []);
2173
+ const currencyId = this.safeString(response, 'currency');
2174
+ currency = this.safeCurrency(currencyId, currency);
2175
+ const parsed = this.parseDepositAddresses(chains, [currency['code']], false, {
2176
+ 'currency': currency['id'],
2177
+ });
2178
+ return this.indexBy(parsed, 'network');
2179
+ }
2177
2180
  /**
2178
2181
  * @method
2179
2182
  * @name gate#fetchDepositAddress
@@ -2186,74 +2189,30 @@ export default class gate extends Exchange {
2186
2189
  */
2187
2190
  async fetchDepositAddress(code, params = {}) {
2188
2191
  await this.loadMarkets();
2189
- const currency = this.currency(code);
2190
- const rawNetwork = this.safeStringUpper(params, 'network');
2191
- params = this.omit(params, 'network');
2192
- const request = {
2193
- 'currency': currency['id'], // todo: currencies have network-junctions
2194
- };
2195
- const response = await this.privateWalletGetDepositAddress(this.extend(request, params));
2192
+ let networkCode = undefined;
2193
+ [networkCode, params] = this.handleNetworkCodeAndParams(params);
2194
+ const chainsIndexedById = await this.fetchDepositAddressesByNetwork(code, params);
2195
+ const selectedNetworkId = this.selectNetworkCodeFromUnifiedNetworks(code, networkCode, chainsIndexedById);
2196
+ return chainsIndexedById[selectedNetworkId];
2197
+ }
2198
+ parseDepositAddress(depositAddress, currency = undefined) {
2196
2199
  //
2197
- // {
2198
- // "currency": "XRP",
2199
- // "address": "rHcFoo6a9qT5NHiVn1THQRhsEGcxtYCV4d 391331007",
2200
- // "multichain_addresses": [
2201
- // {
2202
- // "chain": "XRP",
2203
- // "address": "rHcFoo6a9qT5NHiVn1THQRhsEGcxtYCV4d",
2204
- // "payment_id": "391331007",
2205
- // "payment_name": "Tag",
2206
- // "obtain_failed": 0
2207
- // }
2208
- // ]
2209
- // }
2200
+ // {
2201
+ // chain: "BTC",
2202
+ // address: "1Nxu.......Ys",
2203
+ // payment_id: "",
2204
+ // payment_name: "",
2205
+ // obtain_failed: "0",
2206
+ // }
2210
2207
  //
2211
- const currencyId = this.safeString(response, 'currency');
2212
- code = this.safeCurrencyCode(currencyId);
2213
- const networkId = this.networkCodeToId(rawNetwork, code);
2214
- let network = undefined;
2215
- let tag = undefined;
2216
- let address = undefined;
2217
- if (networkId !== undefined) {
2218
- const addresses = this.safeValue(response, 'multichain_addresses');
2219
- for (let i = 0; i < addresses.length; i++) {
2220
- const entry = addresses[i];
2221
- const entryNetwork = this.safeString(entry, 'chain');
2222
- if (networkId === entryNetwork) {
2223
- const obtainFailed = this.safeInteger(entry, 'obtain_failed');
2224
- if (obtainFailed) {
2225
- break;
2226
- }
2227
- address = this.safeString(entry, 'address');
2228
- tag = this.safeString(entry, 'payment_id');
2229
- network = this.networkIdToCode(networkId, code);
2230
- break;
2231
- }
2232
- }
2233
- }
2234
- else {
2235
- const addressField = this.safeString(response, 'address');
2236
- if (addressField !== undefined) {
2237
- if (addressField.indexOf('New address is being generated for you, please wait') >= 0) {
2238
- throw new BadResponse(this.id + ' ' + 'New address is being generated for you, please wait a few seconds and try again to get the address.');
2239
- }
2240
- if (addressField.indexOf(' ') >= 0) {
2241
- const splitted = addressField.split(' ');
2242
- address = splitted[0];
2243
- tag = splitted[1];
2244
- }
2245
- else {
2246
- address = addressField;
2247
- }
2248
- }
2249
- }
2208
+ const address = this.safeString(depositAddress, 'address');
2250
2209
  this.checkAddress(address);
2251
2210
  return {
2252
- 'info': response,
2253
- 'currency': code,
2254
- 'network': network,
2211
+ 'info': depositAddress,
2212
+ 'currency': this.safeString(currency, 'code'),
2255
2213
  'address': address,
2256
- 'tag': tag,
2214
+ 'tag': this.safeString(depositAddress, 'payment_id'),
2215
+ 'network': this.networkIdToCode(this.safeString(depositAddress, 'chain')),
2257
2216
  };
2258
2217
  }
2259
2218
  /**
@@ -3986,15 +3945,10 @@ export default class gate extends Exchange {
3986
3945
  if (tag !== undefined) {
3987
3946
  request['memo'] = tag;
3988
3947
  }
3989
- const networks = this.safeValue(this.options, 'networks', {});
3990
- let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
3991
- network = this.safeStringLower(networks, network, network); // handle ETH>ERC20 alias
3992
- if (network !== undefined) {
3993
- request['chain'] = network;
3994
- params = this.omit(params, 'network');
3995
- }
3996
- else {
3997
- request['chain'] = currency['id']; // todo: currencies have network-junctions
3948
+ let networkCode = undefined;
3949
+ [networkCode, params] = this.handleNetworkCodeAndParams(params);
3950
+ if (networkCode !== undefined) {
3951
+ request['chain'] = this.networkCodeToId(networkCode);
3998
3952
  }
3999
3953
  const response = await this.privateWithdrawalsPostWithdrawals(this.extend(request, params));
4000
3954
  //
package/js/src/phemex.js CHANGED
@@ -673,7 +673,8 @@ export default class phemex extends Exchange {
673
673
  // }
674
674
  //
675
675
  const id = this.safeString(market, 'symbol');
676
- const baseId = this.safeString2(market, 'baseCurrency', 'contractUnderlyingAssets');
676
+ const contractUnderlyingAssets = this.safeString(market, 'contractUnderlyingAssets');
677
+ const baseId = this.safeString(market, 'baseCurrency', contractUnderlyingAssets);
677
678
  const quoteId = this.safeString(market, 'quoteCurrency');
678
679
  const settleId = this.safeString(market, 'settleCurrency');
679
680
  let base = this.safeCurrencyCode(baseId);
@@ -683,6 +684,10 @@ export default class phemex extends Exchange {
683
684
  let inverse = false;
684
685
  if (settleId !== quoteId) {
685
686
  inverse = true;
687
+ // some unhandled cases
688
+ if (!('baseCurrency' in market) && base === quote) {
689
+ base = settle;
690
+ }
686
691
  }
687
692
  const priceScale = this.safeInteger(market, 'priceScale');
688
693
  const ratioScale = this.safeInteger(market, 'ratioScale');
@@ -872,7 +877,7 @@ export default class phemex extends Exchange {
872
877
  * @returns {object[]} an array of objects representing market data
873
878
  */
874
879
  async fetchMarkets(params = {}) {
875
- const v2Products = await this.v2GetPublicProducts(params);
880
+ const v2ProductsPromise = this.v2GetPublicProducts(params);
876
881
  //
877
882
  // {
878
883
  // "code":0,
@@ -1022,7 +1027,8 @@ export default class phemex extends Exchange {
1022
1027
  // }
1023
1028
  // }
1024
1029
  //
1025
- const v1Products = await this.v1GetExchangePublicProducts(params);
1030
+ const v1ProductsPromise = this.v1GetExchangePublicProducts(params);
1031
+ const [v2Products, v1Products] = await Promise.all([v2ProductsPromise, v1ProductsPromise]);
1026
1032
  const v1ProductsData = this.safeValue(v1Products, 'data', []);
1027
1033
  //
1028
1034
  // {
@@ -1059,14 +1065,14 @@ export default class phemex extends Exchange {
1059
1065
  // ]
1060
1066
  // }
1061
1067
  //
1062
- const v2ProductsData = this.safeValue(v2Products, 'data', {});
1063
- let products = this.safeValue(v2ProductsData, 'products', []);
1064
- const perpetualProductsV2 = this.safeValue(v2ProductsData, 'perpProductsV2', []);
1068
+ const v2ProductsData = this.safeDict(v2Products, 'data', {});
1069
+ let products = this.safeList(v2ProductsData, 'products', []);
1070
+ const perpetualProductsV2 = this.safeList(v2ProductsData, 'perpProductsV2', []);
1065
1071
  products = this.arrayConcat(products, perpetualProductsV2);
1066
- let riskLimits = this.safeValue(v2ProductsData, 'riskLimits', []);
1067
- const riskLimitsV2 = this.safeValue(v2ProductsData, 'riskLimitsV2', []);
1072
+ let riskLimits = this.safeList(v2ProductsData, 'riskLimits', []);
1073
+ const riskLimitsV2 = this.safeList(v2ProductsData, 'riskLimitsV2', []);
1068
1074
  riskLimits = this.arrayConcat(riskLimits, riskLimitsV2);
1069
- const currencies = this.safeValue(v2ProductsData, 'currencies', []);
1075
+ const currencies = this.safeList(v2ProductsData, 'currencies', []);
1070
1076
  const riskLimitsById = this.indexBy(riskLimits, 'symbol');
1071
1077
  const v1ProductsById = this.indexBy(v1ProductsData, 'symbol');
1072
1078
  const currenciesByCode = this.indexBy(currencies, 'currency');
@@ -1076,15 +1082,15 @@ export default class phemex extends Exchange {
1076
1082
  const type = this.safeStringLower(market, 'type');
1077
1083
  if ((type === 'perpetual') || (type === 'perpetualv2') || (type === 'perpetualpilot')) {
1078
1084
  const id = this.safeString(market, 'symbol');
1079
- const riskLimitValues = this.safeValue(riskLimitsById, id, {});
1085
+ const riskLimitValues = this.safeDict(riskLimitsById, id, {});
1080
1086
  market = this.extend(market, riskLimitValues);
1081
- const v1ProductsValues = this.safeValue(v1ProductsById, id, {});
1087
+ const v1ProductsValues = this.safeDict(v1ProductsById, id, {});
1082
1088
  market = this.extend(market, v1ProductsValues);
1083
1089
  market = this.parseSwapMarket(market);
1084
1090
  }
1085
1091
  else {
1086
1092
  const baseCurrency = this.safeString(market, 'baseCurrency');
1087
- const currencyValues = this.safeValue(currenciesByCode, baseCurrency, {});
1093
+ const currencyValues = this.safeDict(currenciesByCode, baseCurrency, {});
1088
1094
  const valueScale = this.safeString(currencyValues, 'valueScale', '8');
1089
1095
  market = this.extend(market, { 'valueScale': valueScale });
1090
1096
  market = this.parseSpotMarket(market);
@@ -121,7 +121,7 @@ export default class bitmart extends bitmartRest {
121
121
  const url = this.implodeHostname(this.urls['api']['ws'][type]['public']);
122
122
  const channelType = (type === 'spot') ? 'spot' : 'futures';
123
123
  const actionType = (type === 'spot') ? 'op' : 'action';
124
- let rawSubscriptions = [];
124
+ const rawSubscriptions = [];
125
125
  const messageHashes = [];
126
126
  for (let i = 0; i < symbols.length; i++) {
127
127
  const market = this.market(symbols[i]);
@@ -130,9 +130,10 @@ export default class bitmart extends bitmartRest {
130
130
  messageHashes.push(channel + ':' + market['symbol']);
131
131
  }
132
132
  // as an exclusion, futures "tickers" need one generic request for all symbols
133
- if ((type !== 'spot') && (channel === 'ticker')) {
134
- rawSubscriptions = [channelType + '/' + channel];
135
- }
133
+ // if ((type !== 'spot') && (channel === 'ticker')) {
134
+ // rawSubscriptions = [ channelType + '/' + channel ];
135
+ // }
136
+ // Exchange update from 2025-02-11 supports subscription by trading pair for swap
136
137
  const request = {
137
138
  'args': rawSubscriptions,
138
139
  };
@@ -948,39 +949,44 @@ export default class bitmart extends bitmartRest {
948
949
  }
949
950
  parseWsTrade(trade, market = undefined) {
950
951
  // spot
951
- // {
952
- // "price": "52700.50",
953
- // "s_t": 1630982050,
954
- // "side": "buy",
955
- // "size": "0.00112",
956
- // "symbol": "BTC_USDT"
957
- // }
952
+ // {
953
+ // "ms_t": 1740320841473,
954
+ // "price": "2806.54",
955
+ // "s_t": 1740320841,
956
+ // "side": "sell",
957
+ // "size": "0.77598",
958
+ // "symbol": "ETH_USDT"
959
+ // }
960
+ //
958
961
  // swap
959
- // {
960
- // "trade_id":6798697637,
961
- // "contract_id":1,
962
- // "symbol":"BTCUSDT",
963
- // "deal_price":"39735.8",
964
- // "deal_vol":"2",
965
- // "type":0,
966
- // "way":1,
967
- // "create_time":1701618503,
968
- // "create_time_mill":1701618503517,
969
- // "created_at":"2023-12-03T15:48:23.517518538Z"
970
- // }
962
+ // {
963
+ // "trade_id": "3000000245258661",
964
+ // "symbol": "ETHUSDT",
965
+ // "deal_price": "2811.1",
966
+ // "deal_vol": "1858",
967
+ // "way": 2,
968
+ // "m": true,
969
+ // "created_at": "2025-02-23T13:59:59.646490751Z"
970
+ // }
971
971
  //
972
- const contractId = this.safeString(trade, 'contract_id');
973
- const marketType = (contractId === undefined) ? 'spot' : 'swap';
974
- const marketDelimiter = (marketType === 'spot') ? '_' : '';
975
- const timestamp = this.safeInteger(trade, 'create_time_mill', this.safeTimestamp(trade, 's_t'));
976
972
  const marketId = this.safeString(trade, 'symbol');
973
+ market = this.safeMarket(marketId, market);
974
+ let timestamp = this.safeInteger(trade, 'ms_t');
975
+ let datetime = undefined;
976
+ if (timestamp === undefined) {
977
+ datetime = this.safeString(trade, 'created_at');
978
+ timestamp = this.parse8601(datetime);
979
+ }
980
+ else {
981
+ datetime = this.iso8601(timestamp);
982
+ }
977
983
  return this.safeTrade({
978
984
  'info': trade,
979
985
  'id': this.safeString(trade, 'trade_id'),
980
986
  'order': undefined,
981
987
  'timestamp': timestamp,
982
- 'datetime': this.iso8601(timestamp),
983
- 'symbol': this.safeSymbol(marketId, market, marketDelimiter, marketType),
988
+ 'datetime': datetime,
989
+ 'symbol': market['symbol'],
984
990
  'type': undefined,
985
991
  'side': this.safeString(trade, 'side'),
986
992
  'price': this.safeString2(trade, 'price', 'deal_price'),
@@ -1006,20 +1012,22 @@ export default class bitmart extends bitmartRest {
1006
1012
  // ],
1007
1013
  // "table": "spot/ticker"
1008
1014
  // }
1009
- // {
1010
- // "group":"futures/ticker",
1011
- // "data":{
1012
- // "symbol":"BTCUSDT",
1013
- // "volume_24":"117387.58",
1014
- // "fair_price":"146.24",
1015
- // "last_price":"146.24",
1016
- // "range":"147.17",
1017
- // "ask_price": "147.11",
1018
- // "ask_vol": "1",
1019
- // "bid_price": "142.11",
1020
- // "bid_vol": "1"
1021
- // }
1022
- // }
1015
+ //
1016
+ // {
1017
+ // "data": {
1018
+ // "symbol": "ETHUSDT",
1019
+ // "last_price": "2807.73",
1020
+ // "volume_24": "2227011952",
1021
+ // "range": "0.0273398194664491",
1022
+ // "mark_price": "2807.5",
1023
+ // "index_price": "2808.71047619",
1024
+ // "ask_price": "2808.04",
1025
+ // "ask_vol": "7371",
1026
+ // "bid_price": "2807.28",
1027
+ // "bid_vol": "3561"
1028
+ // },
1029
+ // "group": "futures/ticker:ETHUSDT@100ms"
1030
+ // }
1023
1031
  //
1024
1032
  this.handleBidAsk(client, message);
1025
1033
  const table = this.safeString(message, 'table');
@@ -1044,17 +1052,19 @@ export default class bitmart extends bitmartRest {
1044
1052
  }
1045
1053
  parseWsSwapTicker(ticker, market = undefined) {
1046
1054
  //
1047
- // {
1048
- // "symbol":"BTCUSDT",
1049
- // "volume_24":"117387.58",
1050
- // "fair_price":"146.24",
1051
- // "last_price":"146.24",
1052
- // "range":"147.17",
1053
- // "ask_price": "147.11",
1054
- // "ask_vol": "1",
1055
- // "bid_price": "142.11",
1056
- // "bid_vol": "1"
1057
- // }
1055
+ // {
1056
+ // "symbol": "ETHUSDT",
1057
+ // "last_price": "2807.73",
1058
+ // "volume_24": "2227011952",
1059
+ // "range": "0.0273398194664491",
1060
+ // "mark_price": "2807.5",
1061
+ // "index_price": "2808.71047619",
1062
+ // "ask_price": "2808.04",
1063
+ // "ask_vol": "7371",
1064
+ // "bid_price": "2807.28",
1065
+ // "bid_vol": "3561"
1066
+ // }
1067
+ //
1058
1068
  const marketId = this.safeString(ticker, 'symbol');
1059
1069
  return this.safeTicker({
1060
1070
  'symbol': this.safeSymbol(marketId, market, '', 'swap'),
@@ -1073,10 +1083,12 @@ export default class bitmart extends bitmartRest {
1073
1083
  'previousClose': undefined,
1074
1084
  'change': undefined,
1075
1085
  'percentage': undefined,
1076
- 'average': this.safeString(ticker, 'fair_price'),
1086
+ 'average': undefined,
1077
1087
  'baseVolume': undefined,
1078
1088
  'quoteVolume': this.safeString(ticker, 'volume_24'),
1079
1089
  'info': ticker,
1090
+ 'markPrice': this.safeString(ticker, 'mark_price'),
1091
+ 'indexPrice': this.safeString(ticker, 'index_price'),
1080
1092
  }, market);
1081
1093
  }
1082
1094
  /**
@@ -77,7 +77,7 @@ export default class bitopro extends bitoproRest {
77
77
  endPart = market['id'];
78
78
  }
79
79
  else {
80
- endPart = market['id'] + ':' + limit;
80
+ endPart = market['id'] + ':' + this.numberToString(limit);
81
81
  }
82
82
  const orderbook = await this.watchPublic('order-books', messageHash, endPart);
83
83
  return orderbook.limit();
@@ -2024,6 +2024,11 @@ export default class gate extends gateRest {
2024
2024
  'signature': signature,
2025
2025
  'req_param': reqParams,
2026
2026
  };
2027
+ if ((channel === 'spot.order_place') || (channel === 'futures.order_place')) {
2028
+ payload['req_header'] = {
2029
+ 'x-gate-channel-id': 'ccxt',
2030
+ };
2031
+ }
2027
2032
  const request = {
2028
2033
  'id': requestId,
2029
2034
  'time': time,
@@ -50,6 +50,11 @@ export default class vertex extends vertexRest {
50
50
  },
51
51
  'ws': {
52
52
  'inflate': true,
53
+ 'options': {
54
+ 'headers': {
55
+ 'Sec-WebSocket-Extensions': 'permessage-deflate', // requires permessage-deflate extension, maybe we can set this in client implementation when inflate is true
56
+ },
57
+ },
53
58
  },
54
59
  },
55
60
  'streaming': {
@@ -518,12 +518,12 @@ export default class tradeogre extends Exchange {
518
518
  throw new BadRequest(this.id + ' createOrder does not support market orders');
519
519
  }
520
520
  if (price === undefined) {
521
- throw new ArgumentsRequired(this.id + ' createOrder requires a limit parameter');
521
+ throw new ArgumentsRequired(this.id + ' createOrder requires a price parameter');
522
522
  }
523
523
  const request = {
524
524
  'market': market['id'],
525
- 'quantity': this.parseToNumeric(this.amountToPrecision(symbol, amount)),
526
- 'price': this.parseToNumeric(this.priceToPrecision(symbol, price)),
525
+ 'quantity': this.amountToPrecision(symbol, amount),
526
+ 'price': this.priceToPrecision(symbol, price),
527
527
  };
528
528
  let response = undefined;
529
529
  if (side === 'buy') {