<commit_before>"use strict";

/*  ------------------------------------------------------------------------ */

const [processPath, , exchangeId = null, exchangeSymbol = null] = process.argv.filter (x => !x.startsWith ('--'))
const verbose = process.argv.includes ('--verbose') || false

/*  ------------------------------------------------------------------------ */

const asTable   = require ('as-table')
    , util      = require ('util')
    , log       = require ('ololog')
    , ansi      = require ('ansicolor').nice
    , fs        = require ('fs')
    , assert    = require ('assert')
    , ccxt      = require ('../ccxt')
    , countries = require ('../countries')

/*  ------------------------------------------------------------------------ */

const warn = log.bright.yellow.error // .error goes to stderr

/*  ------------------------------------------------------------------------ */

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

/*  ------------------------------------------------------------------------ */

log.bright ('\nTESTING', { exchange: exchangeId, symbol: exchangeSymbol || 'all' }, '\n')

/*  ------------------------------------------------------------------------ */

let proxies = [
    '',
    'https://cors-anywhere.herokuapp.com/',
    'https://crossorigin.me/',
    // 'http://cors-proxy.htmldriven.com/?url=', // we don't want this for now
]

/*  ------------------------------------------------------------------------ */

const exchange = new (ccxt)[exchangeId] ({ verbose: verbose, enabledRateLimit: true })

//-----------------------------------------------------------------------------

let apiKeys = JSON.parse (fs.readFileSync ('./keys.json', 'utf8'))[exchangeId]

Object.assign (exchange, apiKeys)

if (exchange.urls['test'])
    exchange.urls['api'] = exchange.urls['test']; // move to testnet/sandbox if possible

const verboseList = [ ];
if (verboseList.indexOf (exchange.id) >= 0) {
    exchange.verbose = true
}

//-----------------------------------------------------------------------------

var countryName = function (code) {
    return ((typeof countries[code] !== 'undefined') ? countries[code] : code)
}

//-----------------------------------------------------------------------------

let human_value = function (price) {
    return typeof price == 'undefined' ? 'N/A' : price
}

//-----------------------------------------------------------------------------

let testTicker = async (exchange, symbol) => {
    log (symbol.green, 'fetching ticker...')
    let ticker = await exchange.fetchTicker (symbol)
    log (symbol.green, 'ticker',
        ticker['datetime'],
        'high: '    + human_value (ticker['high']),
        'low: '     + human_value (ticker['low']),
        'bid: '     + human_value (ticker['bid']),
        'ask: '     + human_value (ticker['ask']),
        'volume: '  + human_value (ticker['quoteVolume']))

    if (('bid' in ticker && 'ask' in ticker) && (ticker['bid'] && ticker['ask']))
        assert (ticker['bid'] <= ticker['ask'])

    return ticker;
}

let testOrderBook = async (exchange, symbol) => {
    log (symbol.green, 'fetching order book...')
    let orderbook = await exchange.fetchOrderBook (symbol)
    log (symbol.green,
        orderbook['datetime'],
        'bid: '       + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][0]) : 'N/A'),
        'bidVolume: ' + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][1]) : 'N/A'),
        'ask: '       + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][0]) : 'N/A'),
        'askVolume: ' + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][1]) : 'N/A'))

    let bids = orderbook.bids
    if (bids.length > 1) {
        let first = 0
        let last = bids.length - 1
        if (bids[first][0] < bids[last][0])
            log (symbol, 'bids reversed!'.red.bright, bids[first][0], bids[last][0])
        else if (bids[first][0] > bids[last][0])
            log (symbol.green, 'bids ok')
    }
    let asks = orderbook.asks
    if (asks.length > 1) {
        let first = 0
        let last = asks.length - 1
        if (asks[first][0] > asks[last][0])
            log (symbol, 'asks reversed!'.red.bright, asks[first][0], asks[last][0])
        else if (asks[first][0] < asks[last][0])
            log (symbol.green, 'asks ok')
    }

    if (bids.length && asks.length)
        if (bids[0][0] > asks[0][0])
            log (this.id, symbol, 'order book', 'bid is greater than ask!'.red.bright)

    return orderbook
}

//-----------------------------------------------------------------------------

let testTrades = async (exchange, symbol) => {
    log (symbol.green, 'fetching trades...')
    let trades = await exchange.fetchTrades (symbol)
    log (symbol.green, 'fetched', Object.values (trades).length.toString ().green, 'trades')
    return trades
}

//-----------------------------------------------------------------------------

let testSymbol = async (exchange, symbol) => {

    await testTicker (exchange, symbol)

    if (exchange.hasFetchTickers) {

        log ('fetching all tickers at once...')
        let tickers = await exchange.fetchTickers ()
        log ('fetched', Object.keys (tickers).length.toString ().green, 'tickers')
<commit_msg>better orderbook test<commit_after>"use strict";

/*  ------------------------------------------------------------------------ */

const [processPath, , exchangeId = null, exchangeSymbol = null] = process.argv.filter (x => !x.startsWith ('--'))
const verbose = process.argv.includes ('--verbose') || false

/*  ------------------------------------------------------------------------ */

const asTable   = require ('as-table')
    , util      = require ('util')
    , log       = require ('ololog')
    , ansi      = require ('ansicolor').nice
    , fs        = require ('fs')
    , assert    = require ('assert')
    , ccxt      = require ('../ccxt')
    , countries = require ('../countries')

/*  ------------------------------------------------------------------------ */

const warn = log.bright.yellow.error // .error goes to stderr

/*  ------------------------------------------------------------------------ */

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

/*  ------------------------------------------------------------------------ */

log.bright ('\nTESTING', { exchange: exchangeId, symbol: exchangeSymbol || 'all' }, '\n')

/*  ------------------------------------------------------------------------ */

let proxies = [
    '',
    'https://cors-anywhere.herokuapp.com/',
    'https://crossorigin.me/',
    // 'http://cors-proxy.htmldriven.com/?url=', // we don't want this for now
]

/*  ------------------------------------------------------------------------ */

const exchange = new (ccxt)[exchangeId] ({ verbose: verbose, enabledRateLimit: true })

//-----------------------------------------------------------------------------

let apiKeys = JSON.parse (fs.readFileSync ('./keys.json', 'utf8'))[exchangeId]

Object.assign (exchange, apiKeys)

if (exchange.urls['test'])
    exchange.urls['api'] = exchange.urls['test']; // move to testnet/sandbox if possible

const verboseList = [ ];
if (verboseList.indexOf (exchange.id) >= 0) {
    exchange.verbose = true
}

//-----------------------------------------------------------------------------

var countryName = function (code) {
    return ((typeof countries[code] !== 'undefined') ? countries[code] : code)
}

//-----------------------------------------------------------------------------

let human_value = function (price) {
    return typeof price == 'undefined' ? 'N/A' : price
}

//-----------------------------------------------------------------------------

let testTicker = async (exchange, symbol) => {
    log (symbol.green, 'fetching ticker...')
    let ticker = await exchange.fetchTicker (symbol)
    log (symbol.green, 'ticker',
        ticker['datetime'],
        'high: '    + human_value (ticker['high']),
        'low: '     + human_value (ticker['low']),
        'bid: '     + human_value (ticker['bid']),
        'ask: '     + human_value (ticker['ask']),
        'volume: '  + human_value (ticker['quoteVolume']))

    if (('bid' in ticker && 'ask' in ticker) && (ticker['bid'] && ticker['ask']))
        assert (ticker['bid'] <= ticker['ask'])

    return ticker;
}

let testOrderBook = async (exchange, symbol) => {
    log (symbol.green, 'fetching order book...')
    let orderbook = await exchange.fetchOrderBook (symbol)
    log (symbol.green,
        orderbook['datetime'],
        'bid: '       + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][0]) : 'N/A'),
        'bidVolume: ' + ((orderbook.bids.length > 0) ? human_value (orderbook.bids[0][1]) : 'N/A'),
        'ask: '       + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][0]) : 'N/A'),
        'askVolume: ' + ((orderbook.asks.length > 0) ? human_value (orderbook.asks[0][1]) : 'N/A'))

    let bids = orderbook.bids
    let asks = orderbook.asks

    if (bids.length > 1)
        assert (bids[0][0] >= bids[bids.length - 1][0])

    if (asks.length > 1)
        assert (asks[0][0] <= asks[asks.length - 1][0])

    if (bids.length && asks.length)
        assert (bids[0][0] <= asks[0][0])

    return orderbook
}

//-----------------------------------------------------------------------------

let testTrades = async (exchange, symbol) => {
    log (symbol.green, 'fetching trades...')
    let trades = await exchange.fetchTrades (symbol)
    log (symbol.green, 'fetched', Object.values (trades).length.toString ().green, 'trades')
    return trades
}

//-----------------------------------------------------------------------------

let testSymbol = async (exchange, symbol) => {

    await testTicker (exchange, symbol)

    if (exchange.hasFetchTickers) {

        log ('fetching all tickers at once...')
        let tickers = await exchange.fetchTickers ()
        log ('fetched', Object.keys (tickers).length.toString ().green, 'tickers')

{'fraction_non_alphanumeric': 0.33950496979146366, 'fraction_numerical': 0.006626388618203079, 'mean_word_length': 1.48378509196515, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 35, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2915265', 'n_tokens_mistral': 2926, 'n_tokens_neox': 2805, 'n_words': 656}