UNPKG

@jmparsons/ccxt

Version:

A JavaScript / Python / PHP cryptocurrency trading library with support for 100+ exchanges

123 lines (89 loc) 4.17 kB
"use strict"; const ccxt = require ('../../ccxt.js') const asTable = require ('as-table') const log = require ('ololog').configure ({ locate: false }) require ('ansicolor').nice; let printSupportedExchanges = function () { log ('Supported exchanges:', ccxt.exchanges.join (', ').green) } let printUsage = function () { log ('Usage: node', process.argv[1], 'id1'.green, 'id2'.yellow, 'id3'.blue, '...') printSupportedExchanges () } let printExchangeSymbolsAndMarkets = function (exchange) { log (getExchangeSymbols (exchange)) log (getExchangeMarketsTable (exchange)) } let getExchangeMarketsTable = (exchange) => { return asTable.configure ({ delimiter: ' | ' }) (Object.values (markets)) } let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms)); let proxies = [ '', // no proxy by default 'https://crossorigin.me/', 'https://cors-anywhere.herokuapp.com/', ] ;(async function main () { if (process.argv.length > 3) { let ids = process.argv.slice (2) let exchanges = {} log (ids.join (', ').yellow) // load all markets from all exchanges for (let id of ids) { // instantiate the exchange by id let exchange = new ccxt[id] () // save it in a dictionary under its id for future use exchanges[id] = exchange // load all markets from the exchange let markets = await exchange.loadMarkets () // basic round-robin proxy scheduler let currentProxy = 0 let maxRetries = proxies.length for (let numRetries = 0; numRetries < maxRetries; numRetries++) { try { // try to load exchange markets using current proxy exchange.proxy = proxies[currentProxy] await exchange.loadMarkets () } catch (e) { // rotate proxies in case of connectivity errors, catch all other exceptions // swallow connectivity exceptions only if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) { log.bright.yellow ('[DDoS Protection Error] ' + e.message) } else if (e instanceof ccxt.RequestTimeout) { log.bright.yellow ('[Timeout Error] ' + e.message) } else if (e instanceof ccxt.AuthenticationError) { log.bright.yellow ('[Authentication Error] ' + e.message) } else if (e instanceof ccxt.ExchangeNotAvailable) { log.bright.yellow ('[Exchange Not Available Error] ' + e.message) } else if (e instanceof ccxt.ExchangeError) { log.bright.yellow ('[Exchange Error] ' + e.message) } else { throw e; // rethrow all other exceptions } // retry next proxy in round-robin fashion in case of error currentProxy = ++currentProxy % proxies.length } } log (id.green, 'loaded', exchange.symbols.length.toString ().green, 'markets') } log ('Loaded all markets'.green) // get all unique symbols let uniqueSymbols = ccxt.unique (ccxt.flatten (ids.map (id => exchanges[id].symbols))) // filter out symbols that are not present on at least two exchanges let arbitrableSymbols = uniqueSymbols .filter (symbol => ids.filter (id => (exchanges[id].symbols.indexOf (symbol) >= 0)).length > 1) .sort ((id1, id2) => (id1 > id2) ? 1 : ((id2 > id1) ? -1 : 0)) // print a table of arbitrable symbols let table = arbitrableSymbols.map (symbol => { let row = { symbol } for (let id of ids) if (exchanges[id].symbols.indexOf (symbol) >= 0) row[id] = id return row }) log (asTable.configure ({ delimiter: ' | ' }) (table)) } else { printUsage () } process.exit () }) ()