@icgio/icg-exchanges 1.40.50 → 1.41.0
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/lib/exchanges/ascendex.js +1 -3
- package/lib/exchanges/biconomy.js +2 -2
- package/lib/exchanges/binance.js +1 -0
- package/lib/exchanges/bingx.js +2 -1
- package/lib/exchanges/bitget.js +1 -0
- package/lib/exchanges/bithumb.js +1 -3
- package/lib/exchanges/bitkub.js +1 -3
- package/lib/exchanges/bitmart.js +49 -32
- package/lib/exchanges/bitmex.js +1 -0
- package/lib/exchanges/bitrue.js +2 -1
- package/lib/exchanges/bitstamp.js +1 -0
- package/lib/exchanges/blofin.js +1 -0
- package/lib/exchanges/btse.js +1 -3
- package/lib/exchanges/bybit.js +48 -35
- package/lib/exchanges/coinbase.js +3 -1
- package/lib/exchanges/coinstore.js +1 -3
- package/lib/exchanges/coinw.js +48 -32
- package/lib/exchanges/cryptocom.js +1 -0
- package/lib/exchanges/deepcoin.js +1 -0
- package/lib/exchanges/digifinex.js +1 -0
- package/lib/exchanges/exchange-base.js +12 -46
- package/lib/exchanges/fastex.js +1 -3
- package/lib/exchanges/gate.js +49 -34
- package/lib/exchanges/gemini.js +1 -0
- package/lib/exchanges/hashkey.js +1 -0
- package/lib/exchanges/hashkeyglobal.js +1 -0
- package/lib/exchanges/hitbtc.js +44 -27
- package/lib/exchanges/hkbitex.js +1 -3
- package/lib/exchanges/htx.js +4 -3
- package/lib/exchanges/indodax.js +1 -3
- package/lib/exchanges/kraken.js +1 -0
- package/lib/exchanges/kucoin.js +2 -1
- package/lib/exchanges/lbank.js +2 -1
- package/lib/exchanges/mexc.js +2 -1
- package/lib/exchanges/okx.js +51 -34
- package/lib/exchanges/phemex.js +47 -31
- package/lib/exchanges/poloniex.js +43 -27
- package/lib/exchanges/swft.js +1 -3
- package/lib/exchanges/upbit.js +1 -0
- package/lib/exchanges/weex.js +1 -3
- package/lib/exchanges/xt.js +2 -1
- package/package.json +1 -1
|
@@ -479,9 +479,7 @@ module.exports = class Ascendex extends ExchangeBase {
|
|
|
479
479
|
}
|
|
480
480
|
this.private_limiter.process(get_trades_base, pair, timeframe_in_ms, cb)
|
|
481
481
|
}
|
|
482
|
-
get_history_trades
|
|
483
|
-
this._get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb)
|
|
484
|
-
}
|
|
482
|
+
// get_history_trades — not implemented, no native absolute-window endpoint
|
|
485
483
|
static get_min_amount(cb) {
|
|
486
484
|
let min_cur_amount = {}
|
|
487
485
|
needle.get(base_url + '/api/pro/v1/cash/products', (err, res, body) => {
|
|
@@ -590,7 +590,7 @@ module.exports = class Biconomy extends ExchangeBase {
|
|
|
590
590
|
for (const record of records) {
|
|
591
591
|
const close_time_ms = Math.floor(parseFloat(record.ftime) * 1000)
|
|
592
592
|
if (close_time_ms < start_time_in_ms) {
|
|
593
|
-
cb({ success: true, body: sort_history_rows(filter_history_in_range(rows, start_time_in_ms, end_time_in_ms)) })
|
|
593
|
+
cb({ success: true, body: utils.merge_trades_with_same_id(sort_history_rows(filter_history_in_range(rows, start_time_in_ms, end_time_in_ms))) })
|
|
594
594
|
return
|
|
595
595
|
}
|
|
596
596
|
if (close_time_ms >= end_time_in_ms || parseFloat(record.deal_stock) <= 0) continue
|
|
@@ -612,7 +612,7 @@ module.exports = class Biconomy extends ExchangeBase {
|
|
|
612
612
|
offset += limit
|
|
613
613
|
await sleep(50)
|
|
614
614
|
}
|
|
615
|
-
cb({ success: true, body: sort_history_rows(filter_history_in_range(rows, start_time_in_ms, end_time_in_ms)) })
|
|
615
|
+
cb({ success: true, body: utils.merge_trades_with_same_id(sort_history_rows(filter_history_in_range(rows, start_time_in_ms, end_time_in_ms))) })
|
|
616
616
|
})().catch((error) => {
|
|
617
617
|
cb({ success: false, error: error?.error || error_codes.other, body: error?.body })
|
|
618
618
|
})
|
package/lib/exchanges/binance.js
CHANGED
|
@@ -715,6 +715,7 @@ module.exports = class Binance extends ExchangeBase {
|
|
|
715
715
|
delay_ms: 250,
|
|
716
716
|
})
|
|
717
717
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
718
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
718
719
|
cb({ success: true, body: trades })
|
|
719
720
|
})().catch((error) => cb(error))
|
|
720
721
|
}
|
package/lib/exchanges/bingx.js
CHANGED
|
@@ -591,7 +591,8 @@ module.exports = class Bingx extends ExchangeBase {
|
|
|
591
591
|
}))
|
|
592
592
|
},
|
|
593
593
|
})
|
|
594
|
-
|
|
594
|
+
const merged = utils.merge_trades_with_same_id(sort_history_rows(rows))
|
|
595
|
+
cb({ success: true, body: merged })
|
|
595
596
|
})().catch((error) => {
|
|
596
597
|
cb({ success: false, error: error_codes.other, body: error?.body })
|
|
597
598
|
})
|
package/lib/exchanges/bitget.js
CHANGED
|
@@ -571,6 +571,7 @@ module.exports = class Bitget extends ExchangeBase {
|
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
573
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
574
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
574
575
|
cb({ success: true, body: trades })
|
|
575
576
|
})().catch((error) => cb(error))
|
|
576
577
|
}
|
package/lib/exchanges/bithumb.js
CHANGED
|
@@ -425,9 +425,7 @@ module.exports = class Bithumb extends ExchangeBase {
|
|
|
425
425
|
}
|
|
426
426
|
this.private_limiter.process(get_trades_base, pair, timeframe_in_ms, cb)
|
|
427
427
|
}
|
|
428
|
-
get_history_trades
|
|
429
|
-
this._get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb)
|
|
430
|
-
}
|
|
428
|
+
// get_history_trades — not implemented, no native absolute-window endpoint
|
|
431
429
|
get_trades_id_type(pair, id, type, timeframe_in_ms, cb) {
|
|
432
430
|
let [cur, quote_cur] = utils.parse_pair(pair)
|
|
433
431
|
let get_trades_id_type_base = (pair, id, timeframe_in_ms, cb) => {
|
package/lib/exchanges/bitkub.js
CHANGED
|
@@ -314,9 +314,7 @@ module.exports = class Bitkub extends ExchangeBase {
|
|
|
314
314
|
}
|
|
315
315
|
this.private_limiter.process(get_trades_base, pair, timeframe_in_ms, cb)
|
|
316
316
|
}
|
|
317
|
-
get_history_trades
|
|
318
|
-
this._get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb)
|
|
319
|
-
}
|
|
317
|
+
// get_history_trades — not implemented, no native absolute-window endpoint
|
|
320
318
|
_get_trades_page(pair, page, cb) {
|
|
321
319
|
let get_trades_base = (pair, page, cb) => {
|
|
322
320
|
let [api_key, secret_key] = this.api_secret_key
|
package/lib/exchanges/bitmart.js
CHANGED
|
@@ -10,6 +10,7 @@ const ExchangeBase = require('./exchange-base.js')
|
|
|
10
10
|
|
|
11
11
|
const { error_codes } = require('../error_codes.json')
|
|
12
12
|
const { utils, rate_limiter: Limiter } = require('@icgio/icg-utils')
|
|
13
|
+
const { fetch_split_windows, sort_history_rows } = ExchangeBase.history_utils
|
|
13
14
|
|
|
14
15
|
function parse_body(body) {
|
|
15
16
|
if (body) {
|
|
@@ -529,38 +530,54 @@ module.exports = class Bitmart extends ExchangeBase {
|
|
|
529
530
|
get_history_trades(pair, start_time_in_ms, end_time_in_ms, cb) {
|
|
530
531
|
let get_history_trades_base = (pair, start_time_in_ms, end_time_in_ms, cb) => {
|
|
531
532
|
let [api_key, secret_key] = this.api_secret_key
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
533
|
+
;(async () => {
|
|
534
|
+
const rows = await fetch_split_windows({
|
|
535
|
+
start_ms: start_time_in_ms,
|
|
536
|
+
stop_ms: end_time_in_ms,
|
|
537
|
+
initial_window_ms: Math.max(end_time_in_ms - start_time_in_ms, 60 * 1000),
|
|
538
|
+
page_limit: 200,
|
|
539
|
+
fetch_window: async (window_start_ms, window_stop_ms) =>
|
|
540
|
+
await new Promise((resolve, reject) => {
|
|
541
|
+
let params = {
|
|
542
|
+
endTime: window_stop_ms - 1,
|
|
543
|
+
limit: 200,
|
|
544
|
+
orderMode: 'spot',
|
|
545
|
+
startTime: window_start_ms,
|
|
546
|
+
symbol: pre_process_pair(pair),
|
|
547
|
+
}
|
|
548
|
+
let url = 'https://api-cloud.bitmart.com/spot/v4/query/trades'
|
|
549
|
+
let options = get_options(api_key, Date.now(), this.memo, params, secret_key)
|
|
550
|
+
needle.post(url, params, options, (err, res, body) => {
|
|
551
|
+
body = parse_body(body)
|
|
552
|
+
if (body && body.code === 1000 && body.data && Array.isArray(body.data)) {
|
|
553
|
+
resolve(
|
|
554
|
+
body.data.map((t) => ({
|
|
555
|
+
order_id: t.orderId.toString(),
|
|
556
|
+
pair,
|
|
557
|
+
type: t.side,
|
|
558
|
+
price: parseFloat(t.price),
|
|
559
|
+
amount: parseFloat(t.size),
|
|
560
|
+
total: parseFloat(t.notional),
|
|
561
|
+
open_time: new Date(t.createTime),
|
|
562
|
+
close_time: new Date(t.updateTime),
|
|
563
|
+
fees: {
|
|
564
|
+
[post_process_cur(t.feeCoinName)]: parseFloat(t.fee),
|
|
565
|
+
},
|
|
566
|
+
...(t.tradeRole != null ? { role: t.tradeRole } : {}),
|
|
567
|
+
})),
|
|
568
|
+
)
|
|
569
|
+
} else if (body) {
|
|
570
|
+
reject({ error: error_codes.other, body })
|
|
571
|
+
} else {
|
|
572
|
+
reject({ error: error_codes.timeout })
|
|
573
|
+
}
|
|
574
|
+
})
|
|
575
|
+
}),
|
|
576
|
+
})
|
|
577
|
+
const merged = utils.merge_trades_with_same_id(rows)
|
|
578
|
+
cb({ success: true, body: sort_history_rows(merged) })
|
|
579
|
+
})().catch((error) => {
|
|
580
|
+
cb({ success: false, error: error?.error || error_codes.other, body: error?.body })
|
|
564
581
|
})
|
|
565
582
|
}
|
|
566
583
|
this.private_limiter.process(get_history_trades_base, pair, start_time_in_ms, end_time_in_ms, cb)
|
package/lib/exchanges/bitmex.js
CHANGED
|
@@ -751,6 +751,7 @@ module.exports = class Bitmex extends ExchangeBase {
|
|
|
751
751
|
delay_ms: 250,
|
|
752
752
|
})
|
|
753
753
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
754
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
754
755
|
cb({ success: true, body: trades })
|
|
755
756
|
})().catch((error) => cb(error))
|
|
756
757
|
}
|
package/lib/exchanges/bitrue.js
CHANGED
|
@@ -567,7 +567,8 @@ module.exports = class Bitrue extends ExchangeBase {
|
|
|
567
567
|
})
|
|
568
568
|
}),
|
|
569
569
|
})
|
|
570
|
-
|
|
570
|
+
const merged = utils.merge_trades_with_same_id(sort_history_rows(rows))
|
|
571
|
+
cb({ success: true, body: merged })
|
|
571
572
|
})().catch((error) => {
|
|
572
573
|
cb({ success: false, error: error?.error || error_codes.other, body: error?.body })
|
|
573
574
|
})
|
|
@@ -438,6 +438,7 @@ module.exports = class Bitstamp extends ExchangeBase {
|
|
|
438
438
|
await sleep(250)
|
|
439
439
|
}
|
|
440
440
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
441
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
441
442
|
cb({ success: true, body: trades })
|
|
442
443
|
})().catch((error) => cb(error))
|
|
443
444
|
}
|
package/lib/exchanges/blofin.js
CHANGED
|
@@ -653,6 +653,7 @@ module.exports = class Blofin extends ExchangeBase {
|
|
|
653
653
|
delay_ms: 250,
|
|
654
654
|
})
|
|
655
655
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
656
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
656
657
|
cb({ success: true, body: trades })
|
|
657
658
|
})().catch((error) => cb(error))
|
|
658
659
|
}
|
package/lib/exchanges/btse.js
CHANGED
|
@@ -489,9 +489,7 @@ module.exports = class Btse extends ExchangeBase {
|
|
|
489
489
|
}
|
|
490
490
|
this.private_limiter.process(get_trades_base, pair, timeframe_in_ms, cb)
|
|
491
491
|
}
|
|
492
|
-
get_history_trades
|
|
493
|
-
this._get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb)
|
|
494
|
-
}
|
|
492
|
+
// get_history_trades — not implemented, no native absolute-window endpoint
|
|
495
493
|
get_all_deposits(timeframe_in_ms, cb) {
|
|
496
494
|
let get_all_deposits_base = (timeframe_in_ms, cb) => {
|
|
497
495
|
let [api_key, secret_key] = this.api_secret_key
|
package/lib/exchanges/bybit.js
CHANGED
|
@@ -10,6 +10,7 @@ const ExchangeWs = require('./exchange-ws.js')
|
|
|
10
10
|
|
|
11
11
|
const { error_codes } = require('../error_codes.json')
|
|
12
12
|
const { utils, rate_limiter: Limiter } = require('@icgio/icg-utils')
|
|
13
|
+
const { fetch_split_windows, sort_history_rows } = ExchangeBase.history_utils
|
|
13
14
|
|
|
14
15
|
function get_options(api_key, sign, timestamp) {
|
|
15
16
|
let options = {
|
|
@@ -540,41 +541,53 @@ module.exports = class Bybit extends ExchangeBase {
|
|
|
540
541
|
get_history_trades(pair, start_time_in_ms, end_time_in_ms, cb) {
|
|
541
542
|
let get_history_trades_base = (pair, start_time_in_ms, end_time_in_ms, cb) => {
|
|
542
543
|
let [api_key, secret_key] = this.api_secret_key
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
544
|
+
;(async () => {
|
|
545
|
+
const rows = await fetch_split_windows({
|
|
546
|
+
start_ms: start_time_in_ms,
|
|
547
|
+
stop_ms: end_time_in_ms,
|
|
548
|
+
initial_window_ms: Math.max(end_time_in_ms - start_time_in_ms, 60 * 1000),
|
|
549
|
+
page_limit: 100,
|
|
550
|
+
fetch_window: async (window_start_ms, window_stop_ms) =>
|
|
551
|
+
await new Promise((resolve, reject) => {
|
|
552
|
+
let params = {
|
|
553
|
+
category: 'spot',
|
|
554
|
+
symbol: pre_process_pair(pair),
|
|
555
|
+
startTime: window_start_ms,
|
|
556
|
+
endTime: window_stop_ms,
|
|
557
|
+
limit: 100,
|
|
558
|
+
}
|
|
559
|
+
const timestamp = Date.now().toString()
|
|
560
|
+
let sign = get_signature_bybitv5('GET', api_key, secret_key, params, timestamp)
|
|
561
|
+
let options = get_options(api_key, sign, timestamp)
|
|
562
|
+
let url = 'https://api.bybit.com/v5/execution/list?' + qs.stringify(params)
|
|
563
|
+
needle.get(url, options, (err, res, body) => {
|
|
564
|
+
if (body && body.retCode === 0 && Array.isArray(body.result.list)) {
|
|
565
|
+
resolve(
|
|
566
|
+
body.result.list.map((t) => ({
|
|
567
|
+
order_id: t.orderId,
|
|
568
|
+
pair,
|
|
569
|
+
type: t.side.toLowerCase(),
|
|
570
|
+
price: parseFloat(t.execPrice),
|
|
571
|
+
amount: parseFloat(t.execQty),
|
|
572
|
+
total: parseFloat(t.execPrice) * parseFloat(t.execQty),
|
|
573
|
+
fees: {
|
|
574
|
+
[post_process_cur(t.feeCurrency)]: parseFloat(t.execFee),
|
|
575
|
+
},
|
|
576
|
+
close_time: new Date(parseInt(t.execTime)),
|
|
577
|
+
})),
|
|
578
|
+
)
|
|
579
|
+
} else if (body) {
|
|
580
|
+
reject({ error: error_codes.other, body })
|
|
581
|
+
} else {
|
|
582
|
+
reject({ error: error_codes.timeout })
|
|
583
|
+
}
|
|
584
|
+
})
|
|
585
|
+
}),
|
|
586
|
+
})
|
|
587
|
+
const merged = utils.merge_trades_with_same_id(rows)
|
|
588
|
+
cb({ success: true, body: sort_history_rows(merged) })
|
|
589
|
+
})().catch((error) => {
|
|
590
|
+
cb({ success: false, error: error?.error || error_codes.other, body: error?.body })
|
|
578
591
|
})
|
|
579
592
|
}
|
|
580
593
|
this.private_limiter.process(get_history_trades_base, pair, start_time_in_ms, end_time_in_ms, cb)
|
|
@@ -1994,7 +1994,9 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
1994
1994
|
await sleep(50)
|
|
1995
1995
|
}
|
|
1996
1996
|
}
|
|
1997
|
-
|
|
1997
|
+
let trades = sort_history_rows(filter_history_in_range(results, start_time_in_ms, end_time_in_ms))
|
|
1998
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
1999
|
+
cb({ success: true, body: trades })
|
|
1998
2000
|
} catch (error) {
|
|
1999
2001
|
cb({ success: false, error: error?.error || error_codes.other, body: error?.body })
|
|
2000
2002
|
}
|
|
@@ -477,9 +477,7 @@ module.exports = class Coinstore extends ExchangeBase {
|
|
|
477
477
|
}
|
|
478
478
|
this.private_limiter.process(get_trades_base, pair, timeframe_in_ms, cb)
|
|
479
479
|
}
|
|
480
|
-
get_history_trades
|
|
481
|
-
this._get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb)
|
|
482
|
-
}
|
|
480
|
+
// get_history_trades — not implemented, no native absolute-window endpoint
|
|
483
481
|
static get_precision(cb) {
|
|
484
482
|
const price_precision = {}
|
|
485
483
|
const amount_precision = {}
|
package/lib/exchanges/coinw.js
CHANGED
|
@@ -7,6 +7,7 @@ const needle = require('needle')
|
|
|
7
7
|
const ExchangeWs = require('./exchange-ws.js')
|
|
8
8
|
|
|
9
9
|
const ExchangeBase = require('./exchange-base.js')
|
|
10
|
+
const { fetch_split_windows, sort_history_rows } = ExchangeBase.history_utils
|
|
10
11
|
|
|
11
12
|
const { error_codes } = require('../error_codes.json')
|
|
12
13
|
const { utils, rate_limiter: Limiter } = require('@icgio/icg-utils')
|
|
@@ -506,38 +507,53 @@ module.exports = class Coinw extends ExchangeBase {
|
|
|
506
507
|
get_history_trades(pair, start_time_in_ms, end_time_in_ms, cb) {
|
|
507
508
|
const [api_key, secret_key] = this.api_secret_key
|
|
508
509
|
const get_trades_base = (pair, start_time_in_ms, end_time_in_ms, cb) => {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
.
|
|
524
|
-
.
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
510
|
+
;(async () => {
|
|
511
|
+
const rows = await fetch_split_windows({
|
|
512
|
+
start_ms: start_time_in_ms,
|
|
513
|
+
stop_ms: end_time_in_ms,
|
|
514
|
+
initial_window_ms: Math.max(end_time_in_ms - start_time_in_ms, 60 * 1000),
|
|
515
|
+
page_limit: 100,
|
|
516
|
+
fetch_window: async (window_start_ms, window_stop_ms) =>
|
|
517
|
+
await new Promise((resolve, reject) => {
|
|
518
|
+
const params = {
|
|
519
|
+
api_key,
|
|
520
|
+
currencyPair: pre_process_pair(pair),
|
|
521
|
+
endAt: window_stop_ms,
|
|
522
|
+
startAt: window_start_ms,
|
|
523
|
+
}
|
|
524
|
+
params.sign = get_signature_coinw(secret_key, params)
|
|
525
|
+
needle.post('https://api.coinw.com/api/v1/private?command=returnUTradeHistory', params, options, (_err, _res, body) => {
|
|
526
|
+
body = parse_body(body)
|
|
527
|
+
if (body && body.code === '200') {
|
|
528
|
+
if (!body.data) {
|
|
529
|
+
resolve([])
|
|
530
|
+
} else {
|
|
531
|
+
resolve(
|
|
532
|
+
body.data
|
|
533
|
+
.filter((t) => t.status === '2' || t.status === '3')
|
|
534
|
+
.map((trade) => ({
|
|
535
|
+
order_id: trade.tradeID.toString(),
|
|
536
|
+
pair,
|
|
537
|
+
type: trade.type,
|
|
538
|
+
price: parseFloat(trade.prize), // exchange typo
|
|
539
|
+
amount: parseFloat(trade.success_count),
|
|
540
|
+
total: parseFloat(trade.success_amount),
|
|
541
|
+
close_time: new Date(parseInt(trade.date)),
|
|
542
|
+
})),
|
|
543
|
+
)
|
|
544
|
+
}
|
|
545
|
+
} else if (body) {
|
|
546
|
+
reject({ error: error_codes.other, body })
|
|
547
|
+
} else {
|
|
548
|
+
reject({ error: error_codes.timeout })
|
|
549
|
+
}
|
|
550
|
+
})
|
|
551
|
+
}),
|
|
552
|
+
})
|
|
553
|
+
const merged = utils.merge_trades_with_same_id(rows)
|
|
554
|
+
cb({ success: true, body: sort_history_rows(merged) })
|
|
555
|
+
})().catch((error) => {
|
|
556
|
+
cb({ success: false, error: error?.error || error_codes.other, body: error?.body })
|
|
541
557
|
})
|
|
542
558
|
}
|
|
543
559
|
this.private_limiter.process(get_trades_base, pair, start_time_in_ms, end_time_in_ms, cb)
|
|
@@ -558,6 +558,7 @@ module.exports = class Cryptocom extends ExchangeBase {
|
|
|
558
558
|
delay_ms: 250,
|
|
559
559
|
})
|
|
560
560
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
561
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
561
562
|
cb({ success: true, body: trades })
|
|
562
563
|
})().catch((error) => cb(error))
|
|
563
564
|
}
|
|
@@ -528,6 +528,7 @@ module.exports = class Deepcoin extends ExchangeBase {
|
|
|
528
528
|
delay_ms: 250,
|
|
529
529
|
})
|
|
530
530
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
531
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
531
532
|
cb({ success: true, body: trades })
|
|
532
533
|
})().catch((error) => cb(error))
|
|
533
534
|
}
|
|
@@ -440,6 +440,7 @@ module.exports = class Digifinex extends ExchangeBase {
|
|
|
440
440
|
delay_ms: 250,
|
|
441
441
|
})
|
|
442
442
|
trades = sort_history_rows(filter_history_in_range(trades, start_time_in_ms, end_time_in_ms))
|
|
443
|
+
trades = utils.merge_trades_with_same_id(trades)
|
|
443
444
|
cb({ success: true, body: trades })
|
|
444
445
|
})().catch((error) => cb(error))
|
|
445
446
|
}
|
|
@@ -450,9 +450,14 @@ class ExchangeBase {
|
|
|
450
450
|
// ============================================
|
|
451
451
|
|
|
452
452
|
/**
|
|
453
|
-
* Get trade history for a trading pair
|
|
453
|
+
* Get trade history for a trading pair within a relative time window.
|
|
454
|
+
*
|
|
455
|
+
* Implementations should call utils.merge_trades_with_same_id() before returning,
|
|
456
|
+
* which groups fills by order_id, aggregates amount/total/fees, recalculates price,
|
|
457
|
+
* and populates fill_history[] on every returned trade (even single-fill trades).
|
|
458
|
+
*
|
|
454
459
|
* @param {string} pair - Trading pair
|
|
455
|
-
* @param {number} timeframe_in_ms - Time range in milliseconds
|
|
460
|
+
* @param {number} timeframe_in_ms - Time range in milliseconds (now - timeframe_in_ms .. now)
|
|
456
461
|
* @param {function(ApiResponse<TradeResult[]>): void} cb - Callback with trades
|
|
457
462
|
*/
|
|
458
463
|
get_trades(pair, timeframe_in_ms, cb) {
|
|
@@ -461,7 +466,11 @@ class ExchangeBase {
|
|
|
461
466
|
|
|
462
467
|
/**
|
|
463
468
|
* Get trade history for a trading pair in an absolute time window.
|
|
464
|
-
*
|
|
469
|
+
*
|
|
470
|
+
* Implementations should call utils.merge_trades_with_same_id() before
|
|
471
|
+
* returning, which groups fills by order_id, aggregates amount/total/fees,
|
|
472
|
+
* recalculates price, and populates fill_history[] on every returned trade.
|
|
473
|
+
*
|
|
465
474
|
* @param {string} pair - Trading pair
|
|
466
475
|
* @param {number} start_time_in_ms - Inclusive start timestamp in milliseconds
|
|
467
476
|
* @param {number} end_time_in_ms - Exclusive end timestamp in milliseconds
|
|
@@ -471,49 +480,6 @@ class ExchangeBase {
|
|
|
471
480
|
cb({ success: false, error: `${this.name}: get_history_trades not implemented` })
|
|
472
481
|
}
|
|
473
482
|
|
|
474
|
-
/**
|
|
475
|
-
* Best-effort absolute-window history built from the exchange's existing recent trade endpoint.
|
|
476
|
-
* @param {string} pair
|
|
477
|
-
* @param {number} start_time_in_ms
|
|
478
|
-
* @param {number} end_time_in_ms
|
|
479
|
-
* @param {function(ApiResponse<TradeResult[]>): void} cb
|
|
480
|
-
* @param {{use_all_trades?: boolean}} options
|
|
481
|
-
*/
|
|
482
|
-
_get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb, options = {}) {
|
|
483
|
-
if (!(start_time_in_ms < end_time_in_ms)) {
|
|
484
|
-
cb({ success: true, body: [] })
|
|
485
|
-
return
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
const use_all_trades = options.use_all_trades === true
|
|
489
|
-
const timeframe_in_ms = Math.max(end_time_in_ms - start_time_in_ms, Date.now() - start_time_in_ms, 0)
|
|
490
|
-
const handle = (res) => {
|
|
491
|
-
if (!res || !res.success) {
|
|
492
|
-
cb(res)
|
|
493
|
-
return
|
|
494
|
-
}
|
|
495
|
-
let trades = Array.isArray(res.body) ? res.body : []
|
|
496
|
-
if (pair) {
|
|
497
|
-
trades = trades.filter((trade) => !trade?.pair || trade.pair === pair)
|
|
498
|
-
}
|
|
499
|
-
cb({
|
|
500
|
-
success: true,
|
|
501
|
-
body: ExchangeBase.history_utils.sort_history_rows(ExchangeBase.history_utils.filter_history_in_range(trades, start_time_in_ms, end_time_in_ms)),
|
|
502
|
-
})
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
if (use_all_trades) {
|
|
506
|
-
if (typeof this.get_all_trades !== 'function') {
|
|
507
|
-
cb({ success: false, error: `${this.name}: get_all_trades not implemented` })
|
|
508
|
-
return
|
|
509
|
-
}
|
|
510
|
-
this.get_all_trades(timeframe_in_ms, handle)
|
|
511
|
-
return
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
this.get_trades(pair, timeframe_in_ms, handle)
|
|
515
|
-
}
|
|
516
|
-
|
|
517
483
|
// ============================================
|
|
518
484
|
// Deposit/Withdrawal Methods
|
|
519
485
|
// ============================================
|
package/lib/exchanges/fastex.js
CHANGED
|
@@ -316,9 +316,7 @@ module.exports = class Fastex extends ExchangeBase {
|
|
|
316
316
|
}
|
|
317
317
|
this.private_limiter.process(get_trades_base, pair, cb)
|
|
318
318
|
}
|
|
319
|
-
get_history_trades
|
|
320
|
-
this._get_history_trades_via_timeframe(pair, start_time_in_ms, end_time_in_ms, cb)
|
|
321
|
-
}
|
|
319
|
+
// get_history_trades — not implemented, no native absolute-window endpoint
|
|
322
320
|
static get_min_amount(cb) {
|
|
323
321
|
let min_quote_cur_amount = {}
|
|
324
322
|
needle.get('https://exchange.fastex.com/api/v1/pair/list?items_per_page=100&page=1', (err, res, body) => {
|