ccxt 4.2.52 → 4.2.54
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/README.md +3 -3
- package/build.sh +1 -1
- package/dist/ccxt.browser.js +511 -102
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/binance.js +136 -9
- package/dist/cjs/src/bingx.js +32 -1
- package/dist/cjs/src/bitget.js +1 -0
- package/dist/cjs/src/bitvavo.js +1 -1
- package/dist/cjs/src/bybit.js +19 -0
- package/dist/cjs/src/coinbase.js +186 -12
- package/dist/cjs/src/htx.js +10 -4
- package/dist/cjs/src/pro/binance.js +92 -38
- package/dist/cjs/src/pro/bitvavo.js +1 -1
- package/dist/cjs/src/pro/blockchaincom.js +7 -25
- package/dist/cjs/src/pro/deribit.js +2 -2
- package/dist/cjs/src/pro/gemini.js +1 -1
- package/dist/cjs/src/pro/okx.js +18 -4
- package/dist/cjs/src/whitebit.js +4 -3
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/binance.d.ts +9 -3
- package/js/src/abstract/binancecoinm.d.ts +9 -3
- package/js/src/abstract/binanceus.d.ts +9 -3
- package/js/src/abstract/binanceusdm.d.ts +9 -3
- package/js/src/abstract/coinbase.d.ts +1 -1
- package/js/src/binance.d.ts +4 -0
- package/js/src/binance.js +136 -9
- package/js/src/bingx.d.ts +4 -0
- package/js/src/bingx.js +32 -1
- package/js/src/bitget.js +1 -0
- package/js/src/bitvavo.js +1 -1
- package/js/src/bybit.d.ts +5 -0
- package/js/src/bybit.js +19 -0
- package/js/src/coinbase.d.ts +2 -0
- package/js/src/coinbase.js +186 -12
- package/js/src/htx.js +10 -4
- package/js/src/pro/binance.d.ts +4 -4
- package/js/src/pro/binance.js +92 -38
- package/js/src/pro/bitvavo.js +1 -1
- package/js/src/pro/blockchaincom.d.ts +0 -1
- package/js/src/pro/blockchaincom.js +7 -25
- package/js/src/pro/deribit.js +2 -2
- package/js/src/pro/gemini.js +1 -1
- package/js/src/pro/okx.js +18 -4
- package/js/src/whitebit.js +4 -3
- package/jsdoc2md.js +3 -2
- package/package.json +2 -1
- package/skip-tests.json +26 -9
package/js/src/coinbase.js
CHANGED
|
@@ -54,6 +54,7 @@ export default class coinbase extends Exchange {
|
|
|
54
54
|
'createStopLimitOrder': true,
|
|
55
55
|
'createStopMarketOrder': false,
|
|
56
56
|
'createStopOrder': true,
|
|
57
|
+
'deposit': true,
|
|
57
58
|
'editOrder': true,
|
|
58
59
|
'fetchAccounts': true,
|
|
59
60
|
'fetchBalance': true,
|
|
@@ -65,6 +66,7 @@ export default class coinbase extends Exchange {
|
|
|
65
66
|
'fetchCrossBorrowRate': false,
|
|
66
67
|
'fetchCrossBorrowRates': false,
|
|
67
68
|
'fetchCurrencies': true,
|
|
69
|
+
'fetchDeposit': true,
|
|
68
70
|
'fetchDepositAddress': 'emulated',
|
|
69
71
|
'fetchDepositAddresses': false,
|
|
70
72
|
'fetchDepositAddressesByNetwork': true,
|
|
@@ -193,6 +195,11 @@ export default class coinbase extends Exchange {
|
|
|
193
195
|
},
|
|
194
196
|
},
|
|
195
197
|
'v3': {
|
|
198
|
+
'public': {
|
|
199
|
+
'get': [
|
|
200
|
+
'brokerage/time',
|
|
201
|
+
],
|
|
202
|
+
},
|
|
196
203
|
'private': {
|
|
197
204
|
'get': [
|
|
198
205
|
'brokerage/accounts',
|
|
@@ -210,7 +217,6 @@ export default class coinbase extends Exchange {
|
|
|
210
217
|
'brokerage/product_book',
|
|
211
218
|
'brokerage/best_bid_ask',
|
|
212
219
|
'brokerage/convert/trade/{trade_id}',
|
|
213
|
-
'brokerage/time',
|
|
214
220
|
'brokerage/cfm/balance_summary',
|
|
215
221
|
'brokerage/cfm/positions',
|
|
216
222
|
'brokerage/cfm/positions/{product_id}',
|
|
@@ -341,6 +347,7 @@ export default class coinbase extends Exchange {
|
|
|
341
347
|
'fetchTickers': 'fetchTickersV3',
|
|
342
348
|
'fetchAccounts': 'fetchAccountsV3',
|
|
343
349
|
'fetchBalance': 'v2PrivateGetAccounts',
|
|
350
|
+
'fetchTime': 'v2PublicGetTime',
|
|
344
351
|
'user_native_currency': 'USD', // needed to get fees for v3
|
|
345
352
|
},
|
|
346
353
|
});
|
|
@@ -352,19 +359,36 @@ export default class coinbase extends Exchange {
|
|
|
352
359
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
353
360
|
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-time#http-request
|
|
354
361
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
362
|
+
* @param {string} [params.method] 'v2PublicGetTime' or 'v3PublicGetBrokerageTime' default is 'v2PublicGetTime'
|
|
355
363
|
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
356
364
|
*/
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
365
|
+
const defaultMethod = this.safeString(this.options, 'fetchTime', 'v2PublicGetTime');
|
|
366
|
+
const method = this.safeString(params, 'method', defaultMethod);
|
|
367
|
+
params = this.omit(params, 'method');
|
|
368
|
+
let response = undefined;
|
|
369
|
+
if (method === 'v2PublicGetTime') {
|
|
370
|
+
response = await this.v2PublicGetTime(params);
|
|
371
|
+
//
|
|
372
|
+
// {
|
|
373
|
+
// "data": {
|
|
374
|
+
// "epoch": 1589295679,
|
|
375
|
+
// "iso": "2020-05-12T15:01:19Z"
|
|
376
|
+
// }
|
|
377
|
+
// }
|
|
378
|
+
//
|
|
379
|
+
response = this.safeValue(response, 'data', {});
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
response = await this.v3PublicGetBrokerageTime(params);
|
|
383
|
+
//
|
|
384
|
+
// {
|
|
385
|
+
// "iso": "2024-02-27T03:37:14Z",
|
|
386
|
+
// "epochSeconds": "1709005034",
|
|
387
|
+
// "epochMillis": "1709005034333"
|
|
388
|
+
// }
|
|
389
|
+
//
|
|
390
|
+
}
|
|
391
|
+
return this.safeTimestamp2(response, 'epoch', 'epochSeconds');
|
|
368
392
|
}
|
|
369
393
|
async fetchAccounts(params = {}) {
|
|
370
394
|
/**
|
|
@@ -1760,6 +1784,7 @@ export default class coinbase extends Exchange {
|
|
|
1760
1784
|
response = await this.v3PrivateGetBrokerageAccounts(this.extend(request, params));
|
|
1761
1785
|
}
|
|
1762
1786
|
else {
|
|
1787
|
+
request['limit'] = 100;
|
|
1763
1788
|
response = await this.v2PrivateGetAccounts(this.extend(request, params));
|
|
1764
1789
|
}
|
|
1765
1790
|
//
|
|
@@ -3539,6 +3564,145 @@ export default class coinbase extends Exchange {
|
|
|
3539
3564
|
'network': this.networkIdToCode(networkId, code),
|
|
3540
3565
|
};
|
|
3541
3566
|
}
|
|
3567
|
+
async deposit(code, amount, id, params = {}) {
|
|
3568
|
+
/**
|
|
3569
|
+
* @method
|
|
3570
|
+
* @name coinbase#deposit
|
|
3571
|
+
* @description make a deposit
|
|
3572
|
+
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#deposit-funds
|
|
3573
|
+
* @param {string} code unified currency code
|
|
3574
|
+
* @param {float} amount the amount to deposit
|
|
3575
|
+
* @param {string} id the payment method id to be used for the deposit, can be retrieved from v2PrivateGetPaymentMethods
|
|
3576
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3577
|
+
* @param {string} [params.accountId] the id of the account to deposit into
|
|
3578
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
3579
|
+
*/
|
|
3580
|
+
await this.loadMarkets();
|
|
3581
|
+
let accountId = this.safeString2(params, 'account_id', 'accountId');
|
|
3582
|
+
params = this.omit(params, ['account_id', 'accountId']);
|
|
3583
|
+
if (accountId === undefined) {
|
|
3584
|
+
if (code === undefined) {
|
|
3585
|
+
throw new ArgumentsRequired(this.id + ' deposit() requires an account_id (or accountId) parameter OR a currency code argument');
|
|
3586
|
+
}
|
|
3587
|
+
accountId = await this.findAccountId(code);
|
|
3588
|
+
if (accountId === undefined) {
|
|
3589
|
+
throw new ExchangeError(this.id + ' deposit() could not find account id for ' + code);
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
const request = {
|
|
3593
|
+
'account_id': accountId,
|
|
3594
|
+
'amount': this.numberToString(amount),
|
|
3595
|
+
'currency': code.toUpperCase(),
|
|
3596
|
+
'payment_method': id,
|
|
3597
|
+
};
|
|
3598
|
+
const response = await this.v2PrivatePostAccountsAccountIdDeposits(this.extend(request, params));
|
|
3599
|
+
//
|
|
3600
|
+
// {
|
|
3601
|
+
// "data": {
|
|
3602
|
+
// "id": "67e0eaec-07d7-54c4-a72c-2e92826897df",
|
|
3603
|
+
// "status": "created",
|
|
3604
|
+
// "payment_method": {
|
|
3605
|
+
// "id": "83562370-3e5c-51db-87da-752af5ab9559",
|
|
3606
|
+
// "resource": "payment_method",
|
|
3607
|
+
// "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559"
|
|
3608
|
+
// },
|
|
3609
|
+
// "transaction": {
|
|
3610
|
+
// "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a",
|
|
3611
|
+
// "resource": "transaction",
|
|
3612
|
+
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a"
|
|
3613
|
+
// },
|
|
3614
|
+
// "amount": {
|
|
3615
|
+
// "amount": "10.00",
|
|
3616
|
+
// "currency": "USD"
|
|
3617
|
+
// },
|
|
3618
|
+
// "subtotal": {
|
|
3619
|
+
// "amount": "10.00",
|
|
3620
|
+
// "currency": "USD"
|
|
3621
|
+
// },
|
|
3622
|
+
// "created_at": "2015-01-31T20:49:02Z",
|
|
3623
|
+
// "updated_at": "2015-02-11T16:54:02-08:00",
|
|
3624
|
+
// "resource": "deposit",
|
|
3625
|
+
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/deposits/67e0eaec-07d7-54c4-a72c-2e92826897df",
|
|
3626
|
+
// "committed": true,
|
|
3627
|
+
// "fee": {
|
|
3628
|
+
// "amount": "0.00",
|
|
3629
|
+
// "currency": "USD"
|
|
3630
|
+
// },
|
|
3631
|
+
// "payout_at": "2015-02-18T16:54:00-08:00"
|
|
3632
|
+
// }
|
|
3633
|
+
// }
|
|
3634
|
+
//
|
|
3635
|
+
const data = this.safeDict(response, 'data', {});
|
|
3636
|
+
return this.parseTransaction(data);
|
|
3637
|
+
}
|
|
3638
|
+
async fetchDeposit(id, code = undefined, params = {}) {
|
|
3639
|
+
/**
|
|
3640
|
+
* @method
|
|
3641
|
+
* @name coinbase#fetchDeposit
|
|
3642
|
+
* @description fetch information on a deposit, fiat only, for crypto transactions use fetchLedger
|
|
3643
|
+
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#show-deposit
|
|
3644
|
+
* @param {string} id deposit id
|
|
3645
|
+
* @param {string} [code] unified currency code
|
|
3646
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3647
|
+
* @param {string} [params.accountId] the id of the account that the funds were deposited into
|
|
3648
|
+
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
3649
|
+
*/
|
|
3650
|
+
await this.loadMarkets();
|
|
3651
|
+
let accountId = this.safeString2(params, 'account_id', 'accountId');
|
|
3652
|
+
params = this.omit(params, ['account_id', 'accountId']);
|
|
3653
|
+
if (accountId === undefined) {
|
|
3654
|
+
if (code === undefined) {
|
|
3655
|
+
throw new ArgumentsRequired(this.id + ' fetchDeposit() requires an account_id (or accountId) parameter OR a currency code argument');
|
|
3656
|
+
}
|
|
3657
|
+
accountId = await this.findAccountId(code);
|
|
3658
|
+
if (accountId === undefined) {
|
|
3659
|
+
throw new ExchangeError(this.id + ' fetchDeposit() could not find account id for ' + code);
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
const request = {
|
|
3663
|
+
'account_id': accountId,
|
|
3664
|
+
'deposit_id': id,
|
|
3665
|
+
};
|
|
3666
|
+
const response = await this.v2PrivateGetAccountsAccountIdDepositsDepositId(this.extend(request, params));
|
|
3667
|
+
//
|
|
3668
|
+
// {
|
|
3669
|
+
// "data": {
|
|
3670
|
+
// "id": "67e0eaec-07d7-54c4-a72c-2e92826897df",
|
|
3671
|
+
// "status": "completed",
|
|
3672
|
+
// "payment_method": {
|
|
3673
|
+
// "id": "83562370-3e5c-51db-87da-752af5ab9559",
|
|
3674
|
+
// "resource": "payment_method",
|
|
3675
|
+
// "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559"
|
|
3676
|
+
// },
|
|
3677
|
+
// "transaction": {
|
|
3678
|
+
// "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a",
|
|
3679
|
+
// "resource": "transaction",
|
|
3680
|
+
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a"
|
|
3681
|
+
// },
|
|
3682
|
+
// "amount": {
|
|
3683
|
+
// "amount": "10.00",
|
|
3684
|
+
// "currency": "USD"
|
|
3685
|
+
// },
|
|
3686
|
+
// "subtotal": {
|
|
3687
|
+
// "amount": "10.00",
|
|
3688
|
+
// "currency": "USD"
|
|
3689
|
+
// },
|
|
3690
|
+
// "created_at": "2015-01-31T20:49:02Z",
|
|
3691
|
+
// "updated_at": "2015-02-11T16:54:02-08:00",
|
|
3692
|
+
// "resource": "deposit",
|
|
3693
|
+
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/deposits/67e0eaec-07d7-54c4-a72c-2e92826897df",
|
|
3694
|
+
// "committed": true,
|
|
3695
|
+
// "fee": {
|
|
3696
|
+
// "amount": "0.00",
|
|
3697
|
+
// "currency": "USD"
|
|
3698
|
+
// },
|
|
3699
|
+
// "payout_at": "2015-02-18T16:54:00-08:00"
|
|
3700
|
+
// }
|
|
3701
|
+
// }
|
|
3702
|
+
//
|
|
3703
|
+
const data = this.safeValue(response, 'data', {});
|
|
3704
|
+
return this.parseTransaction(data);
|
|
3705
|
+
}
|
|
3542
3706
|
sign(path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
3543
3707
|
const version = api[0];
|
|
3544
3708
|
const signed = api[1] === 'private';
|
|
@@ -3559,6 +3723,11 @@ export default class coinbase extends Exchange {
|
|
|
3559
3723
|
'Authorization': authorization,
|
|
3560
3724
|
'Content-Type': 'application/json',
|
|
3561
3725
|
};
|
|
3726
|
+
if (method !== 'GET') {
|
|
3727
|
+
if (Object.keys(query).length) {
|
|
3728
|
+
body = this.json(query);
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3562
3731
|
}
|
|
3563
3732
|
else if (this.token && !this.checkRequiredCredentials(false)) {
|
|
3564
3733
|
headers = {
|
|
@@ -3581,6 +3750,11 @@ export default class coinbase extends Exchange {
|
|
|
3581
3750
|
payload = body;
|
|
3582
3751
|
}
|
|
3583
3752
|
}
|
|
3753
|
+
else {
|
|
3754
|
+
if (Object.keys(query).length) {
|
|
3755
|
+
payload += '?' + this.urlencode(query);
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3584
3758
|
const auth = nonce + method + savedPath + payload;
|
|
3585
3759
|
const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256);
|
|
3586
3760
|
headers = {
|
package/js/src/htx.js
CHANGED
|
@@ -1234,9 +1234,10 @@ export default class htx extends Exchange {
|
|
|
1234
1234
|
async fetchStatus(params = {}) {
|
|
1235
1235
|
await this.loadMarkets();
|
|
1236
1236
|
let marketType = undefined;
|
|
1237
|
-
[marketType, params] = this.handleMarketTypeAndParams('
|
|
1237
|
+
[marketType, params] = this.handleMarketTypeAndParams('fetchStatus', undefined, params);
|
|
1238
|
+
const enabledForContracts = this.handleOption('fetchStatus', 'enableForContracts', false); // temp fix for: https://status-linear-swap.huobigroup.com/api/v2/summary.json
|
|
1238
1239
|
let response = undefined;
|
|
1239
|
-
if (marketType !== 'spot') {
|
|
1240
|
+
if (marketType !== 'spot' && enabledForContracts) {
|
|
1240
1241
|
const subType = this.safeString(params, 'subType', this.options['defaultSubType']);
|
|
1241
1242
|
if (marketType === 'swap') {
|
|
1242
1243
|
if (subType === 'linear') {
|
|
@@ -1258,7 +1259,7 @@ export default class htx extends Exchange {
|
|
|
1258
1259
|
response = await this.contractPublicGetHeartbeat();
|
|
1259
1260
|
}
|
|
1260
1261
|
}
|
|
1261
|
-
else {
|
|
1262
|
+
else if (marketType === 'spot') {
|
|
1262
1263
|
response = await this.statusPublicSpotGetApiV2SummaryJson();
|
|
1263
1264
|
}
|
|
1264
1265
|
//
|
|
@@ -1427,7 +1428,12 @@ export default class htx extends Exchange {
|
|
|
1427
1428
|
let url = undefined;
|
|
1428
1429
|
if (marketType === 'contract') {
|
|
1429
1430
|
const statusRaw = this.safeString(response, 'status');
|
|
1430
|
-
|
|
1431
|
+
if (statusRaw === undefined) {
|
|
1432
|
+
status = undefined;
|
|
1433
|
+
}
|
|
1434
|
+
else {
|
|
1435
|
+
status = (statusRaw === 'ok') ? 'ok' : 'maintenance'; // 'ok', 'error'
|
|
1436
|
+
}
|
|
1431
1437
|
updated = this.safeString(response, 'ts');
|
|
1432
1438
|
}
|
|
1433
1439
|
else {
|
package/js/src/pro/binance.d.ts
CHANGED
|
@@ -30,8 +30,8 @@ export default class binance extends binanceRest {
|
|
|
30
30
|
signParams(params?: {}): any;
|
|
31
31
|
authenticate(params?: {}): Promise<void>;
|
|
32
32
|
keepAliveListenKey(params?: {}): Promise<void>;
|
|
33
|
-
setBalanceCache(client: Client, type: any): void;
|
|
34
|
-
loadBalanceSnapshot(client: any, messageHash: any, type: any): Promise<void>;
|
|
33
|
+
setBalanceCache(client: Client, type: any, isPortfolioMargin?: boolean): void;
|
|
34
|
+
loadBalanceSnapshot(client: any, messageHash: any, type: any, isPortfolioMargin: any): Promise<void>;
|
|
35
35
|
fetchBalanceWs(params?: {}): Promise<Balances>;
|
|
36
36
|
handleBalanceWs(client: Client, message: any): void;
|
|
37
37
|
watchBalance(params?: {}): Promise<Balances>;
|
|
@@ -52,8 +52,8 @@ export default class binance extends binanceRest {
|
|
|
52
52
|
parseWsOrder(order: any, market?: any): Order;
|
|
53
53
|
handleOrderUpdate(client: Client, message: any): void;
|
|
54
54
|
watchPositions(symbols?: Strings, since?: Int, limit?: Int, params?: {}): Promise<Position[]>;
|
|
55
|
-
setPositionsCache(client: Client, type: any, symbols?: Strings): void;
|
|
56
|
-
loadPositionsSnapshot(client: any, messageHash: any, type: any): Promise<void>;
|
|
55
|
+
setPositionsCache(client: Client, type: any, symbols?: Strings, isPortfolioMargin?: boolean): void;
|
|
56
|
+
loadPositionsSnapshot(client: any, messageHash: any, type: any, isPortfolioMargin: any): Promise<void>;
|
|
57
57
|
handlePositions(client: any, message: any): void;
|
|
58
58
|
parseWsPosition(position: any, market?: any): Position;
|
|
59
59
|
fetchMyTradesWs(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
|
package/js/src/pro/binance.js
CHANGED
|
@@ -66,6 +66,7 @@ export default class binance extends binanceRest {
|
|
|
66
66
|
'future': 'wss://fstream.binance.com/ws',
|
|
67
67
|
'delivery': 'wss://dstream.binance.com/ws',
|
|
68
68
|
'ws': 'wss://ws-api.binance.com:443/ws-api/v3',
|
|
69
|
+
'papi': 'wss://fstream.binance.com/pm/ws',
|
|
69
70
|
},
|
|
70
71
|
},
|
|
71
72
|
},
|
|
@@ -1241,11 +1242,12 @@ export default class binance extends binanceRest {
|
|
|
1241
1242
|
}
|
|
1242
1243
|
async authenticate(params = {}) {
|
|
1243
1244
|
const time = this.milliseconds();
|
|
1244
|
-
let query = undefined;
|
|
1245
1245
|
let type = undefined;
|
|
1246
|
-
[type,
|
|
1246
|
+
[type, params] = this.handleMarketTypeAndParams('authenticate', undefined, params);
|
|
1247
1247
|
let subType = undefined;
|
|
1248
|
-
[subType,
|
|
1248
|
+
[subType, params] = this.handleSubTypeAndParams('authenticate', undefined, params);
|
|
1249
|
+
let isPortfolioMargin = undefined;
|
|
1250
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'authenticate', 'papi', 'portfolioMargin', false);
|
|
1249
1251
|
if (this.isLinear(type, subType)) {
|
|
1250
1252
|
type = 'future';
|
|
1251
1253
|
}
|
|
@@ -1253,36 +1255,39 @@ export default class binance extends binanceRest {
|
|
|
1253
1255
|
type = 'delivery';
|
|
1254
1256
|
}
|
|
1255
1257
|
let marginMode = undefined;
|
|
1256
|
-
[marginMode,
|
|
1258
|
+
[marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
|
|
1257
1259
|
const isIsolatedMargin = (marginMode === 'isolated');
|
|
1258
1260
|
const isCrossMargin = (marginMode === 'cross') || (marginMode === undefined);
|
|
1259
|
-
const symbol = this.safeString(
|
|
1260
|
-
|
|
1261
|
+
const symbol = this.safeString(params, 'symbol');
|
|
1262
|
+
params = this.omit(params, 'symbol');
|
|
1261
1263
|
const options = this.safeValue(this.options, type, {});
|
|
1262
1264
|
const lastAuthenticatedTime = this.safeInteger(options, 'lastAuthenticatedTime', 0);
|
|
1263
1265
|
const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 1200000);
|
|
1264
1266
|
const delay = this.sum(listenKeyRefreshRate, 10000);
|
|
1265
1267
|
if (time - lastAuthenticatedTime > delay) {
|
|
1266
1268
|
let response = undefined;
|
|
1267
|
-
if (
|
|
1268
|
-
response = await this.
|
|
1269
|
+
if (isPortfolioMargin) {
|
|
1270
|
+
response = await this.papiPostListenKey(params);
|
|
1271
|
+
}
|
|
1272
|
+
else if (type === 'future') {
|
|
1273
|
+
response = await this.fapiPrivatePostListenKey(params);
|
|
1269
1274
|
}
|
|
1270
1275
|
else if (type === 'delivery') {
|
|
1271
|
-
response = await this.dapiPrivatePostListenKey(
|
|
1276
|
+
response = await this.dapiPrivatePostListenKey(params);
|
|
1272
1277
|
}
|
|
1273
1278
|
else if (type === 'margin' && isCrossMargin) {
|
|
1274
|
-
response = await this.sapiPostUserDataStream(
|
|
1279
|
+
response = await this.sapiPostUserDataStream(params);
|
|
1275
1280
|
}
|
|
1276
1281
|
else if (isIsolatedMargin) {
|
|
1277
1282
|
if (symbol === undefined) {
|
|
1278
1283
|
throw new ArgumentsRequired(this.id + ' authenticate() requires a symbol argument for isolated margin mode');
|
|
1279
1284
|
}
|
|
1280
1285
|
const marketId = this.marketId(symbol);
|
|
1281
|
-
|
|
1282
|
-
response = await this.sapiPostUserDataStreamIsolated(
|
|
1286
|
+
params = this.extend(params, { 'symbol': marketId });
|
|
1287
|
+
response = await this.sapiPostUserDataStreamIsolated(params);
|
|
1283
1288
|
}
|
|
1284
1289
|
else {
|
|
1285
|
-
response = await this.publicPostUserDataStream(
|
|
1290
|
+
response = await this.publicPostUserDataStream(params);
|
|
1286
1291
|
}
|
|
1287
1292
|
this.options[type] = this.extend(options, {
|
|
1288
1293
|
'listenKey': this.safeString(response, 'listenKey'),
|
|
@@ -1295,6 +1300,8 @@ export default class binance extends binanceRest {
|
|
|
1295
1300
|
// https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot
|
|
1296
1301
|
let type = this.safeString2(this.options, 'defaultType', 'authenticate', 'spot');
|
|
1297
1302
|
type = this.safeString(params, 'type', type);
|
|
1303
|
+
let isPortfolioMargin = undefined;
|
|
1304
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'keepAliveListenKey', 'papi', 'portfolioMargin', false);
|
|
1298
1305
|
const subTypeInfo = this.handleSubTypeAndParams('keepAliveListenKey', undefined, params);
|
|
1299
1306
|
const subType = subTypeInfo[0];
|
|
1300
1307
|
if (this.isLinear(type, subType)) {
|
|
@@ -1311,28 +1318,35 @@ export default class binance extends binanceRest {
|
|
|
1311
1318
|
}
|
|
1312
1319
|
const request = {};
|
|
1313
1320
|
const symbol = this.safeString(params, 'symbol');
|
|
1314
|
-
|
|
1321
|
+
params = this.omit(params, ['type', 'symbol']);
|
|
1315
1322
|
const time = this.milliseconds();
|
|
1316
1323
|
try {
|
|
1317
|
-
if (
|
|
1318
|
-
await this.
|
|
1324
|
+
if (isPortfolioMargin) {
|
|
1325
|
+
await this.papiPutListenKey(this.extend(request, params));
|
|
1326
|
+
}
|
|
1327
|
+
else if (type === 'future') {
|
|
1328
|
+
await this.fapiPrivatePutListenKey(this.extend(request, params));
|
|
1319
1329
|
}
|
|
1320
1330
|
else if (type === 'delivery') {
|
|
1321
|
-
await this.dapiPrivatePutListenKey(this.extend(request,
|
|
1331
|
+
await this.dapiPrivatePutListenKey(this.extend(request, params));
|
|
1322
1332
|
}
|
|
1323
1333
|
else {
|
|
1324
1334
|
request['listenKey'] = listenKey;
|
|
1325
1335
|
if (type === 'margin') {
|
|
1326
1336
|
request['symbol'] = symbol;
|
|
1327
|
-
await this.sapiPutUserDataStream(this.extend(request,
|
|
1337
|
+
await this.sapiPutUserDataStream(this.extend(request, params));
|
|
1328
1338
|
}
|
|
1329
1339
|
else {
|
|
1330
|
-
await this.publicPutUserDataStream(this.extend(request,
|
|
1340
|
+
await this.publicPutUserDataStream(this.extend(request, params));
|
|
1331
1341
|
}
|
|
1332
1342
|
}
|
|
1333
1343
|
}
|
|
1334
1344
|
catch (error) {
|
|
1335
|
-
|
|
1345
|
+
let urlType = type;
|
|
1346
|
+
if (isPortfolioMargin) {
|
|
1347
|
+
urlType = 'papi';
|
|
1348
|
+
}
|
|
1349
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
1336
1350
|
const client = this.client(url);
|
|
1337
1351
|
const messageHashes = Object.keys(client.futures);
|
|
1338
1352
|
for (let i = 0; i < messageHashes.length; i++) {
|
|
@@ -1364,7 +1378,7 @@ export default class binance extends binanceRest {
|
|
|
1364
1378
|
}
|
|
1365
1379
|
}
|
|
1366
1380
|
}
|
|
1367
|
-
setBalanceCache(client, type) {
|
|
1381
|
+
setBalanceCache(client, type, isPortfolioMargin = false) {
|
|
1368
1382
|
if (type in client.subscriptions) {
|
|
1369
1383
|
return;
|
|
1370
1384
|
}
|
|
@@ -1374,15 +1388,21 @@ export default class binance extends binanceRest {
|
|
|
1374
1388
|
const messageHash = type + ':fetchBalanceSnapshot';
|
|
1375
1389
|
if (!(messageHash in client.futures)) {
|
|
1376
1390
|
client.future(messageHash);
|
|
1377
|
-
this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
|
|
1391
|
+
this.spawn(this.loadBalanceSnapshot, client, messageHash, type, isPortfolioMargin);
|
|
1378
1392
|
}
|
|
1379
1393
|
}
|
|
1380
1394
|
else {
|
|
1381
1395
|
this.balance[type] = {};
|
|
1382
1396
|
}
|
|
1383
1397
|
}
|
|
1384
|
-
async loadBalanceSnapshot(client, messageHash, type) {
|
|
1385
|
-
const
|
|
1398
|
+
async loadBalanceSnapshot(client, messageHash, type, isPortfolioMargin) {
|
|
1399
|
+
const params = {
|
|
1400
|
+
'type': type,
|
|
1401
|
+
};
|
|
1402
|
+
if (isPortfolioMargin) {
|
|
1403
|
+
params['portfolioMargin'] = true;
|
|
1404
|
+
}
|
|
1405
|
+
const response = await this.fetchBalance(params);
|
|
1386
1406
|
this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
|
|
1387
1407
|
// don't remove the future from the .futures cache
|
|
1388
1408
|
const future = client.futures[messageHash];
|
|
@@ -1476,6 +1496,7 @@ export default class binance extends binanceRest {
|
|
|
1476
1496
|
* @name binance#watchBalance
|
|
1477
1497
|
* @description watch balance and get the amount of funds available for trading or funds locked in orders
|
|
1478
1498
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1499
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch the balance of a portfolio margin account
|
|
1479
1500
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
1480
1501
|
*/
|
|
1481
1502
|
await this.loadMarkets();
|
|
@@ -1484,16 +1505,22 @@ export default class binance extends binanceRest {
|
|
|
1484
1505
|
let type = this.safeString(params, 'type', defaultType);
|
|
1485
1506
|
let subType = undefined;
|
|
1486
1507
|
[subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params);
|
|
1508
|
+
let isPortfolioMargin = undefined;
|
|
1509
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchBalance', 'papi', 'portfolioMargin', false);
|
|
1510
|
+
let urlType = type;
|
|
1511
|
+
if (isPortfolioMargin) {
|
|
1512
|
+
urlType = 'papi';
|
|
1513
|
+
}
|
|
1487
1514
|
if (this.isLinear(type, subType)) {
|
|
1488
1515
|
type = 'future';
|
|
1489
1516
|
}
|
|
1490
1517
|
else if (this.isInverse(type, subType)) {
|
|
1491
1518
|
type = 'delivery';
|
|
1492
1519
|
}
|
|
1493
|
-
const url = this.urls['api']['ws'][
|
|
1520
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
1494
1521
|
const client = this.client(url);
|
|
1495
|
-
this.setBalanceCache(client, type);
|
|
1496
|
-
this.setPositionsCache(client, type);
|
|
1522
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
1523
|
+
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
1497
1524
|
const options = this.safeValue(this.options, 'watchBalance');
|
|
1498
1525
|
const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
|
|
1499
1526
|
const awaitBalanceSnapshot = this.safeBool(options, 'awaitBalanceSnapshot', true);
|
|
@@ -2100,11 +2127,14 @@ export default class binance extends binanceRest {
|
|
|
2100
2127
|
* @name binance#watchOrders
|
|
2101
2128
|
* @description watches information on multiple orders made by the user
|
|
2102
2129
|
* @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
|
|
2130
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#event-futures-order-update
|
|
2131
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#event-margin-order-update
|
|
2103
2132
|
* @param {string} symbol unified market symbol of the market the orders were made in
|
|
2104
2133
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2105
2134
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2106
2135
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2107
2136
|
* @param {string|undefined} [params.marginMode] 'cross' or 'isolated', for spot margin
|
|
2137
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch portfolio margin account orders
|
|
2108
2138
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
2109
2139
|
*/
|
|
2110
2140
|
await this.loadMarkets();
|
|
@@ -2133,10 +2163,15 @@ export default class binance extends binanceRest {
|
|
|
2133
2163
|
if ((type === 'margin') || ((type === 'spot') && (marginMode !== undefined))) {
|
|
2134
2164
|
urlType = 'spot'; // spot-margin shares the same stream as regular spot
|
|
2135
2165
|
}
|
|
2166
|
+
let isPortfolioMargin = undefined;
|
|
2167
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchOrders', 'papi', 'portfolioMargin', false);
|
|
2168
|
+
if (isPortfolioMargin) {
|
|
2169
|
+
urlType = 'papi';
|
|
2170
|
+
}
|
|
2136
2171
|
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2137
2172
|
const client = this.client(url);
|
|
2138
|
-
this.setBalanceCache(client, type);
|
|
2139
|
-
this.setPositionsCache(client, type);
|
|
2173
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
2174
|
+
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
2140
2175
|
const message = undefined;
|
|
2141
2176
|
const orders = await this.watch(url, messageHash, message, type);
|
|
2142
2177
|
if (this.newUpdates) {
|
|
@@ -2391,6 +2426,7 @@ export default class binance extends binanceRest {
|
|
|
2391
2426
|
* @description watch all open positions
|
|
2392
2427
|
* @param {string[]|undefined} symbols list of unified market symbols
|
|
2393
2428
|
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
2429
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch positions in a portfolio margin account
|
|
2394
2430
|
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
|
|
2395
2431
|
*/
|
|
2396
2432
|
await this.loadMarkets();
|
|
@@ -2421,10 +2457,16 @@ export default class binance extends binanceRest {
|
|
|
2421
2457
|
type = 'delivery';
|
|
2422
2458
|
}
|
|
2423
2459
|
messageHash = type + ':positions' + messageHash;
|
|
2424
|
-
|
|
2460
|
+
let isPortfolioMargin = undefined;
|
|
2461
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchPositions', 'papi', 'portfolioMargin', false);
|
|
2462
|
+
let urlType = type;
|
|
2463
|
+
if (isPortfolioMargin) {
|
|
2464
|
+
urlType = 'papi';
|
|
2465
|
+
}
|
|
2466
|
+
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2425
2467
|
const client = this.client(url);
|
|
2426
|
-
this.setBalanceCache(client, type);
|
|
2427
|
-
this.setPositionsCache(client, type, symbols);
|
|
2468
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
2469
|
+
this.setPositionsCache(client, type, symbols, isPortfolioMargin);
|
|
2428
2470
|
const fetchPositionsSnapshot = this.handleOption('watchPositions', 'fetchPositionsSnapshot', true);
|
|
2429
2471
|
const awaitPositionsSnapshot = this.safeValue('watchPositions', 'awaitPositionsSnapshot', true);
|
|
2430
2472
|
const cache = this.safeValue(this.positions, type);
|
|
@@ -2438,7 +2480,7 @@ export default class binance extends binanceRest {
|
|
|
2438
2480
|
}
|
|
2439
2481
|
return this.filterBySymbolsSinceLimit(cache, symbols, since, limit, true);
|
|
2440
2482
|
}
|
|
2441
|
-
setPositionsCache(client, type, symbols = undefined) {
|
|
2483
|
+
setPositionsCache(client, type, symbols = undefined, isPortfolioMargin = false) {
|
|
2442
2484
|
if (type === 'spot') {
|
|
2443
2485
|
return;
|
|
2444
2486
|
}
|
|
@@ -2453,15 +2495,21 @@ export default class binance extends binanceRest {
|
|
|
2453
2495
|
const messageHash = type + ':fetchPositionsSnapshot';
|
|
2454
2496
|
if (!(messageHash in client.futures)) {
|
|
2455
2497
|
client.future(messageHash);
|
|
2456
|
-
this.spawn(this.loadPositionsSnapshot, client, messageHash, type);
|
|
2498
|
+
this.spawn(this.loadPositionsSnapshot, client, messageHash, type, isPortfolioMargin);
|
|
2457
2499
|
}
|
|
2458
2500
|
}
|
|
2459
2501
|
else {
|
|
2460
2502
|
this.positions[type] = new ArrayCacheBySymbolBySide();
|
|
2461
2503
|
}
|
|
2462
2504
|
}
|
|
2463
|
-
async loadPositionsSnapshot(client, messageHash, type) {
|
|
2464
|
-
const
|
|
2505
|
+
async loadPositionsSnapshot(client, messageHash, type, isPortfolioMargin) {
|
|
2506
|
+
const params = {
|
|
2507
|
+
'type': type,
|
|
2508
|
+
};
|
|
2509
|
+
if (isPortfolioMargin) {
|
|
2510
|
+
params['portfolioMargin'] = true;
|
|
2511
|
+
}
|
|
2512
|
+
const positions = await this.fetchPositions(undefined, params);
|
|
2465
2513
|
this.positions[type] = new ArrayCacheBySymbolBySide();
|
|
2466
2514
|
const cache = this.positions[type];
|
|
2467
2515
|
for (let i = 0; i < positions.length; i++) {
|
|
@@ -2734,6 +2782,7 @@ export default class binance extends binanceRest {
|
|
|
2734
2782
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
2735
2783
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
2736
2784
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2785
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to watch trades in a portfolio margin account
|
|
2737
2786
|
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
|
2738
2787
|
*/
|
|
2739
2788
|
await this.loadMarkets();
|
|
@@ -2763,10 +2812,15 @@ export default class binance extends binanceRest {
|
|
|
2763
2812
|
if (type === 'margin') {
|
|
2764
2813
|
urlType = 'spot'; // spot-margin shares the same stream as regular spot
|
|
2765
2814
|
}
|
|
2815
|
+
let isPortfolioMargin = undefined;
|
|
2816
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'watchMyTrades', 'papi', 'portfolioMargin', false);
|
|
2817
|
+
if (isPortfolioMargin) {
|
|
2818
|
+
urlType = 'papi';
|
|
2819
|
+
}
|
|
2766
2820
|
const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
|
|
2767
2821
|
const client = this.client(url);
|
|
2768
|
-
this.setBalanceCache(client, type);
|
|
2769
|
-
this.setPositionsCache(client, type);
|
|
2822
|
+
this.setBalanceCache(client, type, isPortfolioMargin);
|
|
2823
|
+
this.setPositionsCache(client, type, undefined, isPortfolioMargin);
|
|
2770
2824
|
const message = undefined;
|
|
2771
2825
|
const trades = await this.watch(url, messageHash, message, type);
|
|
2772
2826
|
if (this.newUpdates) {
|
package/js/src/pro/bitvavo.js
CHANGED
|
@@ -105,7 +105,7 @@ export default class bitvavo extends bitvavoRest {
|
|
|
105
105
|
// "volume": "3587.05020246",
|
|
106
106
|
// "volumeQuote": "708030.17",
|
|
107
107
|
// "bid": "199.56",
|
|
108
|
-
// "bidSize": "4.
|
|
108
|
+
// "bidSize": "4.14730802",
|
|
109
109
|
// "ask": "199.57",
|
|
110
110
|
// "askSize": "6.13642074",
|
|
111
111
|
// "timestamp": 1590770885217
|