ccxt 4.2.36 → 4.2.37
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/CONTRIBUTING.md +3 -2
- package/README.md +5 -5
- package/dist/ccxt.browser.js +495 -198
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/binance.js +147 -65
- package/dist/cjs/src/bitfinex2.js +122 -122
- package/dist/cjs/src/bitmex.js +22 -3
- package/dist/cjs/src/bybit.js +13 -4
- package/dist/cjs/src/pro/gemini.js +190 -3
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/base/types.d.ts +2 -0
- package/js/src/binance.js +147 -65
- package/js/src/bitfinex2.js +122 -122
- package/js/src/bitmex.js +22 -3
- package/js/src/bybit.js +13 -4
- package/js/src/pro/gemini.d.ts +5 -0
- package/js/src/pro/gemini.js +191 -4
- package/package.json +2 -2
|
@@ -16,9 +16,11 @@ class gemini extends gemini$1 {
|
|
|
16
16
|
'watchTicker': false,
|
|
17
17
|
'watchTickers': false,
|
|
18
18
|
'watchTrades': true,
|
|
19
|
+
'watchTradesForSymbols': true,
|
|
19
20
|
'watchMyTrades': false,
|
|
20
21
|
'watchOrders': true,
|
|
21
22
|
'watchOrderBook': true,
|
|
23
|
+
'watchOrderBookForSymbols': true,
|
|
22
24
|
'watchOHLCV': true,
|
|
23
25
|
},
|
|
24
26
|
'hostname': 'api.gemini.com',
|
|
@@ -67,7 +69,29 @@ class gemini extends gemini$1 {
|
|
|
67
69
|
}
|
|
68
70
|
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
69
71
|
}
|
|
72
|
+
async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
|
|
73
|
+
/**
|
|
74
|
+
* @method
|
|
75
|
+
* @name gemini#watchTradesForSymbols
|
|
76
|
+
* @see https://docs.gemini.com/websocket-api/#multi-market-data
|
|
77
|
+
* @description get the list of most recent trades for a list of symbols
|
|
78
|
+
* @param {string[]} symbols unified symbol of the market to fetch trades for
|
|
79
|
+
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
80
|
+
* @param {int} [limit] the maximum amount of trades to fetch
|
|
81
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
82
|
+
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
83
|
+
*/
|
|
84
|
+
const trades = await this.helperForWatchMultipleConstruct('trades', symbols, params);
|
|
85
|
+
if (this.newUpdates) {
|
|
86
|
+
const first = this.safeList(trades, 0);
|
|
87
|
+
const tradeSymbol = this.safeString(first, 'symbol');
|
|
88
|
+
limit = trades.getLimit(tradeSymbol, limit);
|
|
89
|
+
}
|
|
90
|
+
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
|
|
91
|
+
}
|
|
70
92
|
parseWsTrade(trade, market = undefined) {
|
|
93
|
+
//
|
|
94
|
+
// regular v2 trade
|
|
71
95
|
//
|
|
72
96
|
// {
|
|
73
97
|
// "type": "trade",
|
|
@@ -79,11 +103,31 @@ class gemini extends gemini$1 {
|
|
|
79
103
|
// "side": "buy"
|
|
80
104
|
// }
|
|
81
105
|
//
|
|
106
|
+
// multi data trade
|
|
107
|
+
//
|
|
108
|
+
// {
|
|
109
|
+
// "type": "trade",
|
|
110
|
+
// "symbol": "ETHUSD",
|
|
111
|
+
// "tid": "1683002242170204", // this is not TS, but somewhat ID
|
|
112
|
+
// "price": "2299.24",
|
|
113
|
+
// "amount": "0.002662",
|
|
114
|
+
// "makerSide": "bid"
|
|
115
|
+
// }
|
|
116
|
+
//
|
|
82
117
|
const timestamp = this.safeInteger(trade, 'timestamp');
|
|
83
|
-
const id = this.
|
|
118
|
+
const id = this.safeString2(trade, 'event_id', 'tid');
|
|
84
119
|
const priceString = this.safeString(trade, 'price');
|
|
85
|
-
const amountString = this.
|
|
86
|
-
|
|
120
|
+
const amountString = this.safeString2(trade, 'quantity', 'amount');
|
|
121
|
+
let side = this.safeStringLower(trade, 'side');
|
|
122
|
+
if (side === undefined) {
|
|
123
|
+
const marketSide = this.safeStringLower(trade, 'makerSide');
|
|
124
|
+
if (marketSide === 'bid') {
|
|
125
|
+
side = 'sell';
|
|
126
|
+
}
|
|
127
|
+
else if (marketSide === 'ask') {
|
|
128
|
+
side = 'buy';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
87
131
|
const marketId = this.safeStringLower(trade, 'symbol');
|
|
88
132
|
const symbol = this.safeSymbol(marketId, market);
|
|
89
133
|
return this.safeTrade({
|
|
@@ -183,6 +227,34 @@ class gemini extends gemini$1 {
|
|
|
183
227
|
client.resolve(stored, messageHash);
|
|
184
228
|
}
|
|
185
229
|
}
|
|
230
|
+
handleTradesForMultidata(client, trades, timestamp) {
|
|
231
|
+
if (trades !== undefined) {
|
|
232
|
+
const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
233
|
+
const storesForSymbols = {};
|
|
234
|
+
for (let i = 0; i < trades.length; i++) {
|
|
235
|
+
const marketId = trades[i]['symbol'];
|
|
236
|
+
const market = this.safeMarket(marketId.toLowerCase());
|
|
237
|
+
const symbol = market['symbol'];
|
|
238
|
+
const trade = this.parseWsTrade(trades[i], market);
|
|
239
|
+
trade['timestamp'] = timestamp;
|
|
240
|
+
trade['datetime'] = this.iso8601(timestamp);
|
|
241
|
+
let stored = this.safeValue(this.trades, symbol);
|
|
242
|
+
if (stored === undefined) {
|
|
243
|
+
stored = new Cache.ArrayCache(tradesLimit);
|
|
244
|
+
this.trades[symbol] = stored;
|
|
245
|
+
}
|
|
246
|
+
stored.append(trade);
|
|
247
|
+
storesForSymbols[symbol] = stored;
|
|
248
|
+
}
|
|
249
|
+
const symbols = Object.keys(storesForSymbols);
|
|
250
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
251
|
+
const symbol = symbols[i];
|
|
252
|
+
const stored = storesForSymbols[symbol];
|
|
253
|
+
const messageHash = 'trades:' + symbol;
|
|
254
|
+
client.resolve(stored, messageHash);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
186
258
|
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
187
259
|
/**
|
|
188
260
|
* @method
|
|
@@ -328,6 +400,93 @@ class gemini extends gemini$1 {
|
|
|
328
400
|
this.orderbooks[symbol] = orderbook;
|
|
329
401
|
client.resolve(orderbook, messageHash);
|
|
330
402
|
}
|
|
403
|
+
async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
|
|
404
|
+
/**
|
|
405
|
+
* @method
|
|
406
|
+
* @name gemini#watchOrderBookForSymbols
|
|
407
|
+
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
408
|
+
* @see https://docs.gemini.com/websocket-api/#multi-market-data
|
|
409
|
+
* @param {string[]} symbols unified array of symbols
|
|
410
|
+
* @param {int} [limit] the maximum amount of order book entries to return
|
|
411
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
412
|
+
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
413
|
+
*/
|
|
414
|
+
const orderbook = await this.helperForWatchMultipleConstruct('orderbook', symbols, params);
|
|
415
|
+
return orderbook.limit();
|
|
416
|
+
}
|
|
417
|
+
async helperForWatchMultipleConstruct(itemHashName, symbols, params = {}) {
|
|
418
|
+
await this.loadMarkets();
|
|
419
|
+
symbols = this.marketSymbols(symbols, undefined, false, true, true);
|
|
420
|
+
const firstMarket = this.market(symbols[0]);
|
|
421
|
+
if (!firstMarket['spot'] && !firstMarket['linear']) {
|
|
422
|
+
throw new errors.NotSupported(this.id + ' watchMultiple supports only spot or linear-swap symbols');
|
|
423
|
+
}
|
|
424
|
+
const messageHashes = [];
|
|
425
|
+
const marketIds = [];
|
|
426
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
427
|
+
const symbol = symbols[i];
|
|
428
|
+
const messageHash = itemHashName + ':' + symbol;
|
|
429
|
+
messageHashes.push(messageHash);
|
|
430
|
+
const market = this.market(symbol);
|
|
431
|
+
marketIds.push(market['id']);
|
|
432
|
+
}
|
|
433
|
+
const queryStr = marketIds.join(',');
|
|
434
|
+
let url = this.urls['api']['ws'] + '/v1/multimarketdata?symbols=' + queryStr + '&heartbeat=true&';
|
|
435
|
+
if (itemHashName === 'orderbook') {
|
|
436
|
+
url += 'trades=false&bids=true&offers=true';
|
|
437
|
+
}
|
|
438
|
+
else if (itemHashName === 'trades') {
|
|
439
|
+
url += 'trades=true&bids=false&offers=false';
|
|
440
|
+
}
|
|
441
|
+
return await this.watchMultiple(url, messageHashes, undefined);
|
|
442
|
+
}
|
|
443
|
+
handleOrderBookForMultidata(client, rawOrderBookChanges, timestamp, nonce) {
|
|
444
|
+
//
|
|
445
|
+
// rawOrderBookChanges
|
|
446
|
+
//
|
|
447
|
+
// [
|
|
448
|
+
// {
|
|
449
|
+
// delta: "4105123935484.817624",
|
|
450
|
+
// price: "0.000000001",
|
|
451
|
+
// reason: "initial", // initial|cancel|place
|
|
452
|
+
// remaining: "4105123935484.817624",
|
|
453
|
+
// side: "bid", // bid|ask
|
|
454
|
+
// symbol: "SHIBUSD",
|
|
455
|
+
// type: "change", // seems always change
|
|
456
|
+
// },
|
|
457
|
+
// ...
|
|
458
|
+
//
|
|
459
|
+
const marketId = rawOrderBookChanges[0]['symbol'];
|
|
460
|
+
const market = this.safeMarket(marketId.toLowerCase());
|
|
461
|
+
const symbol = market['symbol'];
|
|
462
|
+
const messageHash = 'orderbook:' + symbol;
|
|
463
|
+
let orderbook = this.safeDict(this.orderbooks, symbol);
|
|
464
|
+
if (orderbook === undefined) {
|
|
465
|
+
orderbook = this.orderBook();
|
|
466
|
+
}
|
|
467
|
+
const bids = orderbook['bids'];
|
|
468
|
+
const asks = orderbook['asks'];
|
|
469
|
+
for (let i = 0; i < rawOrderBookChanges.length; i++) {
|
|
470
|
+
const entry = rawOrderBookChanges[i];
|
|
471
|
+
const price = this.safeNumber(entry, 'price');
|
|
472
|
+
const size = this.safeNumber(entry, 'remaining');
|
|
473
|
+
const rawSide = this.safeString(entry, 'side');
|
|
474
|
+
if (rawSide === 'bid') {
|
|
475
|
+
bids.store(price, size);
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
asks.store(price, size);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
orderbook['bids'] = bids;
|
|
482
|
+
orderbook['asks'] = asks;
|
|
483
|
+
orderbook['symbol'] = symbol;
|
|
484
|
+
orderbook['nonce'] = nonce;
|
|
485
|
+
orderbook['timestamp'] = timestamp;
|
|
486
|
+
orderbook['datetime'] = this.iso8601(timestamp);
|
|
487
|
+
this.orderbooks[symbol] = orderbook;
|
|
488
|
+
client.resolve(orderbook, messageHash);
|
|
489
|
+
}
|
|
331
490
|
handleL2Updates(client, message) {
|
|
332
491
|
//
|
|
333
492
|
// {
|
|
@@ -408,6 +567,7 @@ class gemini extends gemini$1 {
|
|
|
408
567
|
// "socket_sequence": 7
|
|
409
568
|
// }
|
|
410
569
|
//
|
|
570
|
+
client.lastPong = this.milliseconds();
|
|
411
571
|
return message;
|
|
412
572
|
}
|
|
413
573
|
handleSubscription(client, message) {
|
|
@@ -610,6 +770,33 @@ class gemini extends gemini$1 {
|
|
|
610
770
|
if (method !== undefined) {
|
|
611
771
|
method.call(this, client, message);
|
|
612
772
|
}
|
|
773
|
+
// handle multimarketdata
|
|
774
|
+
if (type === 'update') {
|
|
775
|
+
const ts = this.safeInteger(message, 'timestampms', this.milliseconds());
|
|
776
|
+
const eventId = this.safeInteger(message, 'eventId');
|
|
777
|
+
const events = this.safeList(message, 'events');
|
|
778
|
+
const orderBookItems = [];
|
|
779
|
+
const collectedEventsOfTrades = [];
|
|
780
|
+
for (let i = 0; i < events.length; i++) {
|
|
781
|
+
const event = events[i];
|
|
782
|
+
const eventType = this.safeString(event, 'type');
|
|
783
|
+
const isOrderBook = (eventType === 'change') && ('side' in event) && this.inArray(event['side'], ['ask', 'bid']);
|
|
784
|
+
if (isOrderBook) {
|
|
785
|
+
orderBookItems.push(event);
|
|
786
|
+
}
|
|
787
|
+
else if (eventType === 'trade') {
|
|
788
|
+
collectedEventsOfTrades.push(events[i]);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
const lengthOb = orderBookItems.length;
|
|
792
|
+
if (lengthOb > 0) {
|
|
793
|
+
this.handleOrderBookForMultidata(client, orderBookItems, ts, eventId);
|
|
794
|
+
}
|
|
795
|
+
const lengthTrades = collectedEventsOfTrades.length;
|
|
796
|
+
if (lengthTrades > 0) {
|
|
797
|
+
this.handleTradesForMultidata(client, collectedEventsOfTrades, ts);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
613
800
|
}
|
|
614
801
|
async authenticate(params = {}) {
|
|
615
802
|
const url = this.safeString(params, 'url');
|
package/js/ccxt.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
|
|
|
4
4
|
import * as errors from './src/base/errors.js';
|
|
5
5
|
import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks } from './src/base/types.js';
|
|
6
6
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
|
|
7
|
-
declare const version = "4.2.
|
|
7
|
+
declare const version = "4.2.36";
|
|
8
8
|
import ace from './src/ace.js';
|
|
9
9
|
import alpaca from './src/alpaca.js';
|
|
10
10
|
import ascendex from './src/ascendex.js';
|
package/js/ccxt.js
CHANGED
|
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
|
|
|
38
38
|
import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, NoChange } from './src/base/errors.js';
|
|
39
39
|
//-----------------------------------------------------------------------------
|
|
40
40
|
// this is updated by vss.js when building
|
|
41
|
-
const version = '4.2.
|
|
41
|
+
const version = '4.2.37';
|
|
42
42
|
Exchange.ccxtVersion = version;
|
|
43
43
|
//-----------------------------------------------------------------------------
|
|
44
44
|
import ace from './src/ace.js';
|
package/js/src/base/types.d.ts
CHANGED
|
@@ -103,6 +103,7 @@ export interface Order {
|
|
|
103
103
|
filled: number;
|
|
104
104
|
remaining: number;
|
|
105
105
|
stopPrice?: number;
|
|
106
|
+
triggerPrice?: number;
|
|
106
107
|
takeProfitPrice?: number;
|
|
107
108
|
stopLossPrice?: number;
|
|
108
109
|
cost: number;
|
|
@@ -234,6 +235,7 @@ export interface Position {
|
|
|
234
235
|
notional?: number;
|
|
235
236
|
leverage?: number;
|
|
236
237
|
unrealizedPnl?: number;
|
|
238
|
+
realizedPnl?: number;
|
|
237
239
|
collateral?: number;
|
|
238
240
|
entryPrice?: number;
|
|
239
241
|
markPrice?: number;
|