ccxt 4.1.91 → 4.1.95

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.
@@ -156,6 +156,7 @@ export default class hitbtc extends Exchange {
156
156
  setLeverage(leverage: any, symbol?: Str, params?: {}): Promise<any>;
157
157
  fetchDepositWithdrawFees(codes?: Strings, params?: {}): Promise<any>;
158
158
  parseDepositWithdrawFee(fee: any, currency?: Currency): any;
159
+ closePosition(symbol: string, side?: OrderSide, params?: {}): Promise<Order>;
159
160
  handleMarginModeAndParams(methodName: any, params?: {}, defaultValue?: any): any[];
160
161
  handleErrors(code: any, reason: any, url: any, method: any, headers: any, body: any, response: any, requestHeaders: any, requestBody: any): any;
161
162
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
package/js/src/hitbtc.js CHANGED
@@ -34,6 +34,7 @@ export default class hitbtc extends Exchange {
34
34
  'addMargin': true,
35
35
  'cancelAllOrders': true,
36
36
  'cancelOrder': true,
37
+ 'closePosition': false,
37
38
  'createDepositAddress': true,
38
39
  'createOrder': true,
39
40
  'createPostOnlyOrder': true,
@@ -2873,6 +2874,9 @@ export default class hitbtc extends Exchange {
2873
2874
  let marketType = undefined;
2874
2875
  let marginMode = undefined;
2875
2876
  [marketType, params] = this.handleMarketTypeAndParams('fetchPositions', undefined, params);
2877
+ if (marketType === 'spot') {
2878
+ marketType = 'swap';
2879
+ }
2876
2880
  [marginMode, params] = this.handleMarginModeAndParams('fetchPositions', params);
2877
2881
  params = this.omit(params, ['marginMode', 'margin']);
2878
2882
  let response = undefined;
@@ -3531,6 +3535,43 @@ export default class hitbtc extends Exchange {
3531
3535
  }
3532
3536
  return result;
3533
3537
  }
3538
+ async closePosition(symbol, side = undefined, params = {}) {
3539
+ /**
3540
+ * @method
3541
+ * @name hitbtc#closePosition
3542
+ * @description closes open positions for a market
3543
+ * @see https://api.hitbtc.com/#close-all-futures-margin-positions
3544
+ * @param {object} [params] extra parameters specific to the okx api endpoint
3545
+ * @param {string} [params.symbol] *required* unified market symbol
3546
+ * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross'
3547
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
3548
+ */
3549
+ await this.loadMarkets();
3550
+ let marginMode = undefined;
3551
+ [marginMode, params] = this.handleMarginModeAndParams('closePosition', params, 'cross');
3552
+ const market = this.market(symbol);
3553
+ const request = {
3554
+ 'symbol': market['id'],
3555
+ 'margin_mode': marginMode,
3556
+ };
3557
+ const response = await this.privateDeleteFuturesPositionMarginModeSymbol(this.extend(request, params));
3558
+ //
3559
+ // {
3560
+ // "id":"202471640",
3561
+ // "symbol":"TRXUSDT_PERP",
3562
+ // "margin_mode":"Cross",
3563
+ // "leverage":"1.00",
3564
+ // "quantity":"0",
3565
+ // "price_entry":"0",
3566
+ // "price_margin_call":"0",
3567
+ // "price_liquidation":"0",
3568
+ // "pnl":"0.001234100000",
3569
+ // "created_at":"2023-10-29T14:46:13.235Z",
3570
+ // "updated_at":"2023-12-19T09:34:40.014Z"
3571
+ // }
3572
+ //
3573
+ return this.parseOrder(response, market);
3574
+ }
3534
3575
  handleMarginModeAndParams(methodName, params = {}, defaultValue = undefined) {
3535
3576
  /**
3536
3577
  * @ignore
@@ -32,14 +32,14 @@ export default class kucoinfutures extends kucoin {
32
32
  'addMargin': true,
33
33
  'cancelAllOrders': true,
34
34
  'cancelOrder': true,
35
+ 'closePosition': true,
36
+ 'closePositions': false,
35
37
  'createDepositAddress': true,
36
38
  'createOrder': true,
37
39
  'createReduceOnlyOrder': true,
38
40
  'createStopLimitOrder': true,
39
41
  'createStopMarketOrder': true,
40
42
  'createStopOrder': true,
41
- 'closePosition': true,
42
- 'closePositions': false,
43
43
  'fetchAccounts': true,
44
44
  'fetchBalance': true,
45
45
  'fetchBorrowRateHistories': false,
@@ -154,6 +154,7 @@ export default class kucoinfutures extends kucoin {
154
154
  'positions': 4.44,
155
155
  'funding-history': 4.44,
156
156
  'sub/api-key': 1,
157
+ 'trade-statistics': 1,
157
158
  },
158
159
  'post': {
159
160
  'withdrawals': 1,
@@ -175,6 +176,7 @@ export default class kucoinfutures extends kucoin {
175
176
  'orders': 4.44,
176
177
  'stopOrders': 1,
177
178
  'sub/api-key': 1,
179
+ 'orders/client-order/{clientOid}': 1,
178
180
  },
179
181
  },
180
182
  'webExchange': {
@@ -1237,13 +1239,27 @@ export default class kucoinfutures extends kucoin {
1237
1239
  * @param {string} id order id
1238
1240
  * @param {string} symbol unified symbol of the market the order was made in
1239
1241
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1242
+ * @param {string} [params.clientOrderId] cancel order by client order id
1240
1243
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1241
1244
  */
1242
1245
  await this.loadMarkets();
1243
- const request = {
1244
- 'orderId': id,
1245
- };
1246
- const response = await this.futuresPrivateDeleteOrdersOrderId(this.extend(request, params));
1246
+ const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
1247
+ params = this.omit(params, ['clientOrderId']);
1248
+ const request = {};
1249
+ let response = undefined;
1250
+ if (clientOrderId !== undefined) {
1251
+ if (symbol === undefined) {
1252
+ throw new ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument when cancelling by clientOrderId');
1253
+ }
1254
+ const market = this.market(symbol);
1255
+ request['symbol'] = market['id'];
1256
+ request['clientOid'] = clientOrderId;
1257
+ response = await this.futuresPrivateDeleteOrdersClientOrderClientOid(this.extend(request, params));
1258
+ }
1259
+ else {
1260
+ request['orderId'] = id;
1261
+ response = await this.futuresPrivateDeleteOrdersOrderId(this.extend(request, params));
1262
+ }
1247
1263
  //
1248
1264
  // {
1249
1265
  // "code": "200000",
package/js/src/okx.js CHANGED
@@ -253,6 +253,7 @@ export default class okx extends Exchange {
253
253
  // rfq
254
254
  'rfq/counterparties': 4,
255
255
  'rfq/maker-instrument-settings': 4,
256
+ 'rfq/mmp-config': 4,
256
257
  'rfq/rfqs': 10,
257
258
  'rfq/quotes': 10,
258
259
  'rfq/trades': 4,
@@ -392,6 +393,7 @@ export default class okx extends Exchange {
392
393
  'rfq/execute-quote': 15,
393
394
  'rfq/maker-instrument-settings': 4,
394
395
  'rfq/mmp-reset': 4,
396
+ 'rfq/mmp-config': 100,
395
397
  'rfq/create-quote': 0.4,
396
398
  'rfq/cancel-quote': 0.4,
397
399
  'rfq/cancel-batch-quotes': 10,
@@ -14,6 +14,8 @@ export default class bingx extends bingxRest {
14
14
  watchOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
15
15
  watchMyTrades(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
16
16
  watchBalance(params?: {}): Promise<Balances>;
17
+ setBalanceCache(client: Client, type: any, subscriptionHash: any, params: any): any;
18
+ loadBalanceSnapshot(client: any, messageHash: any, type: any): Promise<void>;
17
19
  handleErrorMessage(client: any, message: any): boolean;
18
20
  authenticate(params?: {}): Promise<void>;
19
21
  pong(client: any, message: any): Promise<void>;
@@ -8,6 +8,7 @@
8
8
  import bingxRest from '../bingx.js';
9
9
  import { BadRequest, NetworkError } from '../base/errors.js';
10
10
  import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
11
+ import Precise from '../base/Precise.js';
11
12
  // ---------------------------------------------------------------------------
12
13
  export default class bingx extends bingxRest {
13
14
  describe() {
@@ -63,6 +64,10 @@ export default class bingx extends bingxRest {
63
64
  '1d': '1day',
64
65
  },
65
66
  },
67
+ 'watchBalance': {
68
+ 'fetchBalanceSnapshot': true,
69
+ 'awaitBalanceSnapshot': false, // whether to wait for the balance snapshot before providing updates
70
+ },
66
71
  },
67
72
  'streaming': {
68
73
  'keepAlive': 1800000, // 30 minutes
@@ -550,8 +555,41 @@ export default class bingx extends bingxRest {
550
555
  'dataType': 'ACCOUNT_UPDATE',
551
556
  };
552
557
  }
558
+ const client = this.client(url);
559
+ this.setBalanceCache(client, type, subscriptionHash, params);
560
+ let fetchBalanceSnapshot = undefined;
561
+ let awaitBalanceSnapshot = undefined;
562
+ [fetchBalanceSnapshot, params] = this.handleOptionAndParams(params, 'watchBalance', 'fetchBalanceSnapshot', true);
563
+ [awaitBalanceSnapshot, params] = this.handleOptionAndParams(params, 'watchBalance', 'awaitBalanceSnapshot', false);
564
+ if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
565
+ await client.future(type + ':fetchBalanceSnapshot');
566
+ }
553
567
  return await this.watch(url, messageHash, request, subscriptionHash);
554
568
  }
569
+ setBalanceCache(client, type, subscriptionHash, params) {
570
+ if (subscriptionHash in client.subscriptions) {
571
+ return undefined;
572
+ }
573
+ const fetchBalanceSnapshot = this.handleOptionAndParams(params, 'watchBalance', 'fetchBalanceSnapshot', true);
574
+ if (fetchBalanceSnapshot) {
575
+ const messageHash = type + ':fetchBalanceSnapshot';
576
+ if (!(messageHash in client.futures)) {
577
+ client.future(messageHash);
578
+ this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
579
+ }
580
+ }
581
+ else {
582
+ this.balance[type] = {};
583
+ }
584
+ }
585
+ async loadBalanceSnapshot(client, messageHash, type) {
586
+ const response = await this.fetchBalance({ 'type': type });
587
+ this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
588
+ // don't remove the future from the .futures cache
589
+ const future = client.futures[messageHash];
590
+ future.resolve();
591
+ client.resolve(this.balance[type], type + ':balance');
592
+ }
555
593
  handleErrorMessage(client, message) {
556
594
  //
557
595
  // { code: 100400, msg: '', timestamp: 1696245808833 }
@@ -834,9 +872,6 @@ export default class bingx extends bingxRest {
834
872
  const data = this.safeValue(a, 'B', []);
835
873
  const timestamp = this.safeInteger2(message, 'T', 'E');
836
874
  const type = ('P' in a) ? 'swap' : 'spot';
837
- if (!(type in this.balance)) {
838
- this.balance[type] = {};
839
- }
840
875
  this.balance[type]['info'] = data;
841
876
  this.balance[type]['timestamp'] = timestamp;
842
877
  this.balance[type]['datetime'] = this.iso8601(timestamp);
@@ -844,8 +879,12 @@ export default class bingx extends bingxRest {
844
879
  const balance = data[i];
845
880
  const currencyId = this.safeString(balance, 'a');
846
881
  const code = this.safeCurrencyCode(currencyId);
847
- const account = (code in this.balance) ? this.balance[code] : this.account();
848
- account['total'] = this.safeString(balance, 'wb');
882
+ const account = (code in this.balance[type]) ? this.balance[type][code] : this.account();
883
+ account['free'] = this.safeString(balance, 'wb');
884
+ const balanceChange = this.safeString(balance, 'bc');
885
+ if (account['used'] !== undefined) {
886
+ account['used'] = Precise.stringSub(this.safeString(account, 'used'), balanceChange);
887
+ }
849
888
  this.balance[type][code] = account;
850
889
  }
851
890
  this.balance[type] = this.safeBalance(this.balance[type]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.1.91",
3
+ "version": "4.1.95",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",
package/skip-tests.json CHANGED
@@ -53,6 +53,7 @@
53
53
  "skipPhpAsync": true,
54
54
  "skipWs": true,
55
55
  "skipMethods": {
56
+ "fetchStatus": "temporarily failing",
56
57
  "loadMarkets": {
57
58
  "currencyIdAndCode": "i.e. binance does not have currency code BCC",
58
59
  "expiry": "expiry not set for future markets",
@@ -643,6 +644,12 @@
643
644
  "skipMethods": {
644
645
  "loadMarkets": {
645
646
  "active":"is undefined"
647
+ },
648
+ "fetchTicker": {
649
+ "quoteVolume": "quote scale isn't right"
650
+ },
651
+ "fetchTickers": {
652
+ "quoteVolume": "quote scale isn't right"
646
653
  }
647
654
  }
648
655
  },
package/changelog.js DELETED
@@ -1,101 +0,0 @@
1
- import fs from 'fs/promises';
2
-
3
- const owner = 'ccxt';
4
- const repo = 'ccxt';
5
-
6
- const tagsUrl = `https://api.github.com/repos/${owner}/${repo}/tags?per_page=100&page=1`;
7
- const prsUrl = `https://api.github.com/repos/${owner}/${repo}/pulls?state=closed&per_page=100&page=1`;
8
- const filePath = 'CHANGELOG.md';
9
-
10
- const token = 'GITHUB_TOKEN'; // Replace with your GitHub personal access token
11
-
12
- const headers = {
13
- Authorization: `Bearer ${token}`,
14
- 'Content-Type': 'application/json',
15
- };
16
-
17
- // Function to fetch data from GitHub API with pagination
18
- async function fetchPaginatedData(url) {
19
- let page = 1;
20
- let allData = [];
21
-
22
- while (true) {
23
- console.log(`Fetching page ${page}...`)
24
- const response = await fetch(`${url}&page=${page}`, { headers });
25
-
26
- if (!response.ok) {
27
- throw new Error(`Failed to fetch data from ${url}. Status: ${response.status}`);
28
- }
29
-
30
- const data = await response.json();
31
-
32
- if (data.length === 0) {
33
- break; // No more data
34
- }
35
-
36
- allData = allData.concat(data);
37
- page++;
38
- }
39
-
40
- return allData;
41
- }
42
-
43
- // Function to get all tags
44
- async function getAllTags() {
45
- return await fetchPaginatedData(tagsUrl);
46
- }
47
-
48
- // Function to get all PRs
49
- async function getAllPRs() {
50
- return await fetchPaginatedData(prsUrl);
51
- }
52
-
53
- async function fetchAndWriteFullChangelog() {
54
- try {
55
- const tags = await getAllTags();
56
-
57
- const changelogContent = await generateChangelog(tags);
58
- await fs.writeFile('CHANGELOG.md', changelogContent);
59
- console.log('Changelog created successfully.');
60
- } catch (error) {
61
- console.error('Error fetching data:', error.message);
62
- }
63
- }
64
-
65
- async function generateChangelog(tags) {
66
- let changelog = '# Changelog\n\n';
67
-
68
- const prs = await getAllPRs();
69
- for (let i = 0; i < tags.length - 1; i++) {
70
- const currentTag = tags[i];
71
- const nextTag = tags[i + 1];
72
-
73
- changelog += `## ${nextTag.name}\n\n`;
74
-
75
- const commitsBetweenTags = await getCommitsBetweenTags(currentTag.name, nextTag.name);
76
-
77
- commitsBetweenTags.forEach(commit => {
78
- const pr = prs.find(pr => pr.merge_commit_sha === commit);
79
- if (pr) changelog += `- ${pr.title} [#${pr.number}](${pr.html_url})\n`;
80
- });
81
-
82
- changelog += '\n\n';
83
- }
84
-
85
- return changelog;
86
- }
87
-
88
- // Function to get the commits between two tags
89
- async function getCommitsBetweenTags(tag1, tag2) {
90
- console.log(`Fetching commits for ${tag2}...`)
91
- const commitsUrl = `https://api.github.com/repos/${owner}/${repo}/compare/${tag2}...${tag1}`;
92
- const commitsData = await fetch(commitsUrl, { headers }).then(res => res.json()).catch(err => console.log(err));
93
- if (commitsData && commitsData.commits) {
94
- return commitsData.commits.map(commit => commit.sha)
95
- } else {
96
- console.log ('No commits found: ' + JSON.stringify (commitsData))
97
- return [];
98
- }
99
- }
100
-
101
- fetchAndWriteFullChangelog();