@icgio/icg-exchanges 1.40.49 → 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.
Files changed (44) hide show
  1. package/lib/exchanges/ascendex.js +1 -3
  2. package/lib/exchanges/biconomy.js +2 -2
  3. package/lib/exchanges/binance.js +1 -0
  4. package/lib/exchanges/bingx.js +2 -1
  5. package/lib/exchanges/bitget.js +1 -0
  6. package/lib/exchanges/bithumb.js +1 -3
  7. package/lib/exchanges/bitkub.js +1 -3
  8. package/lib/exchanges/bitmart.js +49 -32
  9. package/lib/exchanges/bitmex.js +1 -0
  10. package/lib/exchanges/bitrue.js +2 -1
  11. package/lib/exchanges/bitstamp.js +1 -0
  12. package/lib/exchanges/blofin.js +1 -0
  13. package/lib/exchanges/btse.js +1 -3
  14. package/lib/exchanges/bybit.js +48 -35
  15. package/lib/exchanges/coinbase.js +359 -71
  16. package/lib/exchanges/coinstore.js +1 -3
  17. package/lib/exchanges/coinw.js +48 -32
  18. package/lib/exchanges/cryptocom.js +1 -0
  19. package/lib/exchanges/deepcoin.js +1 -0
  20. package/lib/exchanges/digifinex.js +1 -0
  21. package/lib/exchanges/exchange-base.js +12 -46
  22. package/lib/exchanges/exchange-fix.js +191 -86
  23. package/lib/exchanges/fastex.js +1 -3
  24. package/lib/exchanges/gate.js +49 -34
  25. package/lib/exchanges/gemini.js +1 -0
  26. package/lib/exchanges/hashkey.js +1 -0
  27. package/lib/exchanges/hashkeyglobal.js +1 -0
  28. package/lib/exchanges/hitbtc.js +44 -27
  29. package/lib/exchanges/hkbitex.js +1 -3
  30. package/lib/exchanges/htx.js +4 -3
  31. package/lib/exchanges/indodax.js +1 -3
  32. package/lib/exchanges/kraken.js +1 -0
  33. package/lib/exchanges/kucoin.js +2 -1
  34. package/lib/exchanges/lbank.js +2 -1
  35. package/lib/exchanges/mexc.js +2 -1
  36. package/lib/exchanges/okx.js +51 -34
  37. package/lib/exchanges/phemex.js +47 -31
  38. package/lib/exchanges/poloniex.js +43 -27
  39. package/lib/exchanges/swft.js +1 -3
  40. package/lib/exchanges/upbit.js +1 -0
  41. package/lib/exchanges/weex.js +1 -3
  42. package/lib/exchanges/xt.js +2 -1
  43. package/package.json +1 -1
  44. package/lib/exchanges/coinbase-fix.js +0 -267
@@ -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(pair, start_time_in_ms, end_time_in_ms, cb) {
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
  })
@@ -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
  }
@@ -591,7 +591,8 @@ module.exports = class Bingx extends ExchangeBase {
591
591
  }))
592
592
  },
593
593
  })
594
- cb({ success: true, body: sort_history_rows(rows) })
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
  })
@@ -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
  }
@@ -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(pair, start_time_in_ms, end_time_in_ms, cb) {
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) => {
@@ -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(pair, start_time_in_ms, end_time_in_ms, cb) {
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
@@ -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
- let params = {
533
- endTime: end_time_in_ms,
534
- limit: 200,
535
- orderMode: 'spot',
536
- startTime: start_time_in_ms,
537
- symbol: pre_process_pair(pair),
538
- }
539
- let url = 'https://api-cloud.bitmart.com/spot/v4/query/trades'
540
- let options = get_options(api_key, Date.now(), this.memo, params, secret_key)
541
- needle.post(url, params, options, (err, res, body) => {
542
- body = parse_body(body)
543
- if (body && body.code === 1000 && body.data && Array.isArray(body.data)) {
544
- let trades = body.data.map((t) => ({
545
- order_id: t.orderId.toString(),
546
- pair,
547
- type: t.side,
548
- price: parseFloat(t.price),
549
- amount: parseFloat(t.size),
550
- total: parseFloat(t.notional),
551
- open_time: new Date(t.createTime),
552
- close_time: new Date(t.updateTime),
553
- fees: {
554
- [post_process_cur(t.feeCoinName)]: parseFloat(t.fee),
555
- },
556
- }))
557
- trades = utils.merge_trades_with_same_id(trades)
558
- cb({ success: true, body: trades })
559
- } else if (body) {
560
- cb({ success: false, error: error_codes.other, body })
561
- } else {
562
- cb({ success: false, error: error_codes.timeout })
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)
@@ -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
  }
@@ -567,7 +567,8 @@ module.exports = class Bitrue extends ExchangeBase {
567
567
  })
568
568
  }),
569
569
  })
570
- cb({ success: true, body: sort_history_rows(rows) })
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
  }
@@ -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
  }
@@ -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(pair, start_time_in_ms, end_time_in_ms, cb) {
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
@@ -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
- let params = {
544
- category: 'spot',
545
- symbol: pre_process_pair(pair),
546
- startTime: start_time_in_ms,
547
- endTime: end_time_in_ms,
548
- limit: 100,
549
- }
550
- const timestamp = Date.now().toString()
551
- let sign = get_signature_bybitv5('GET', api_key, secret_key, params, timestamp)
552
- let options = get_options(api_key, sign, timestamp)
553
- let url = 'https://api.bybit.com/v5/execution/list?' + qs.stringify(params)
554
- needle.get(url, options, (err, res, body) => {
555
- if (body && body.retCode === 0 && Array.isArray(body.result.list)) {
556
- let res = body.result.list.map((t) => {
557
- const trade = {
558
- order_id: t.orderId,
559
- pair,
560
- type: t.side.toLowerCase(),
561
- price: parseFloat(t.execPrice),
562
- amount: parseFloat(t.execQty),
563
- total: parseFloat(t.execPrice) * parseFloat(t.execQty),
564
- fees: {
565
- [post_process_cur(t.feeCurrency)]: parseFloat(t.execFee),
566
- },
567
- close_time: new Date(parseInt(t.execTime)),
568
- }
569
- return trade
570
- })
571
- res = utils.merge_trades_with_same_id(res)
572
- cb({ success: true, body: res })
573
- } else if (body) {
574
- cb({ success: false, error: error_codes.other, body })
575
- } else {
576
- cb({ success: false, error: error_codes.timeout })
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)