Removing Current
This commit is contained in:
1 parent
d6c5e91290
commit
a4ed878fcd
4379 files changed
No files matched your search
+61
@@ -0,0 +1,61 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, chai = require ('chai')
|
||||
, assert = chai.assert
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
module.exports = (exchange, balance, method) => {
|
||||
|
||||
let currencies = [
|
||||
'USD',
|
||||
'CNY',
|
||||
'EUR',
|
||||
'BTC',
|
||||
'ETH',
|
||||
'JPY',
|
||||
'LTC',
|
||||
'DASH',
|
||||
'DOGE',
|
||||
'UAH',
|
||||
'RUB',
|
||||
'XRP',
|
||||
]
|
||||
|
||||
// log.yellow (balance)
|
||||
|
||||
assert (typeof balance['total'] === 'object')
|
||||
assert (typeof balance['free'] === 'object')
|
||||
assert (typeof balance['used'] === 'object')
|
||||
|
||||
for (let currency of Object.keys (balance['total'])) {
|
||||
let total = balance['total'][currency]
|
||||
let free = balance['free'][currency]
|
||||
let used = balance['used'][currency]
|
||||
if (total !== undefined && free !== undefined && used !== undefined) {
|
||||
assert (total === free + used, 'free and used do not sum to total ' + exchange.id)
|
||||
}
|
||||
}
|
||||
|
||||
let result = currencies
|
||||
.filter (currency => (currency in balance) &&
|
||||
(balance[currency]['total'] !== undefined))
|
||||
|
||||
if (result.length > 0) {
|
||||
result = result.map (currency => currency + ': ' + balance[currency]['total'])
|
||||
if (exchange.currencies.length > result.length)
|
||||
result = result.join (', ') + ' + more...'
|
||||
else
|
||||
result = result.join (', ')
|
||||
|
||||
} else {
|
||||
|
||||
result = 'zero balance'
|
||||
}
|
||||
|
||||
log (result)
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, currency, method) => {
|
||||
|
||||
const format = {
|
||||
'id': 'btc', // string literal for referencing within an exchange
|
||||
'code': 'BTC', // uppercase string literal of a pair of currencies
|
||||
//----------------------------------------------------------------------
|
||||
// commented temporarily to bring currencies to consistency first
|
||||
// 'name': 'Bitcoin', // uppercase string, base currency, 3 or more letters
|
||||
// 'quote': 'USD', // uppercase string, quote currency, 3 or more letters
|
||||
// 'withdraw': true, // can withdraw
|
||||
// 'deposit': true, // can deposit
|
||||
// 'active': true, // can both withdraw & deposit
|
||||
// 'precision': 8, // number of decimal digits "after the dot"
|
||||
// 'limits': { // value limits when placing orders on this market
|
||||
// 'amount': {
|
||||
// 'min': 0.01, // order amount should be > min
|
||||
// 'max': 1000, // order amount should be < max
|
||||
// },
|
||||
// 'price': {
|
||||
// 'min': 0.01, // order price should be > min
|
||||
// 'max': 1000, // order price should be < max
|
||||
// },
|
||||
// 'cost': { // order cost = price * amount
|
||||
// 'min': 0.01, // order cost should be > min
|
||||
// 'max': 1000, // order cost should be < max
|
||||
// },
|
||||
// },
|
||||
// 'info': {}, // the original unparsed market info from the exchange
|
||||
//----------------------------------------------------------------------
|
||||
}
|
||||
|
||||
expect (currency).to.deep.include.all.keys (format)
|
||||
|
||||
// expect (currency['precision']).to.not.be.undefined
|
||||
|
||||
// expect (currency['limits']['amount']['min']).to.not.be.undefined
|
||||
// expect (currency['limits']['price']['min']).to.not.be.undefined
|
||||
// expect (market['limits']['cost']['min']).to.not.be.undefined
|
||||
|
||||
// log (market)
|
||||
|
||||
return currency
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, testBalance = require ('./test.balance.js')
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
if (!(exchange.has.fetchBalance)) {
|
||||
log (exchange.id.green, ' does not have fetchBalance')
|
||||
return
|
||||
}
|
||||
|
||||
log ('fetching balance...')
|
||||
|
||||
const response = await exchange.fetchBalance ()
|
||||
|
||||
testBalance (exchange, response)
|
||||
|
||||
return response
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOrder = require ('./test.order.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
if (exchange.has.fetchClosedOrders) {
|
||||
|
||||
// log ('fetching closed orders...')
|
||||
|
||||
let orders = await exchange.fetchClosedOrders (symbol)
|
||||
|
||||
log ('fetched', orders.length.toString ().green, 'closed orders, testing each')
|
||||
|
||||
assert (orders instanceof Array)
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
let order = orders[i]
|
||||
testOrder (exchange, order, symbol, now)
|
||||
assert (order.status === 'closed' || order.status === 'canceled')
|
||||
}
|
||||
|
||||
// log (asTable (orders))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching closed orders not supported')
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testCurrency = require ('./test.currency.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchCurrencies...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchCurrencies) {
|
||||
|
||||
// log ('fetching currencies...')
|
||||
|
||||
const method = 'fetchCurrencies'
|
||||
const currencies = await exchange[method] ()
|
||||
Object.values (currencies).forEach (currency => testCurrency (exchange, currency, method))
|
||||
return currencies
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching currencies not supported')
|
||||
}
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTransaction = require ('./test.transaction.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, code) => {
|
||||
|
||||
if (exchange.has.fetchDeposits) {
|
||||
|
||||
// log ('fetching deposits...')
|
||||
|
||||
let transactions = await exchange.fetchDeposits (code)
|
||||
|
||||
log ('fetched', transactions.length.toString ().green, 'deposits, asserting each...')
|
||||
|
||||
assert (transactions instanceof Array)
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < transactions.length; i++) {
|
||||
let transaction = transactions[i]
|
||||
testTransaction (exchange, transaction, code, now)
|
||||
}
|
||||
|
||||
// log (asTable (transactions))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching deposits not supported')
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'bibox', // fetchFundingFees should be rewritten to fetchFundingFee
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchFundingFees...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchFundingFees) {
|
||||
|
||||
// log ('fetching funding fees...')
|
||||
|
||||
const method = 'fetchFundingFees'
|
||||
const fees = await exchange[method] ()
|
||||
log.green (fees)
|
||||
return fees
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching funding fees not supported')
|
||||
}
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOrderBook = require ('./test.orderbook.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
// log (symbol.green, 'fetching order book...')
|
||||
|
||||
const method = 'fetchL2OrderBook'
|
||||
|
||||
if (exchange.has[method]) {
|
||||
|
||||
let orderbook = await exchange[method] (symbol)
|
||||
testOrderBook (exchange, orderbook, method, symbol)
|
||||
return orderbook
|
||||
|
||||
} else {
|
||||
|
||||
log (method + '() not supported')
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testLedgerItem = require ('./test.ledgerItem')
|
||||
|
||||
require ('ansicolor').nice
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, code) => {
|
||||
|
||||
if (exchange.has.fetchLedger) {
|
||||
|
||||
let items = await exchange.fetchLedger (code)
|
||||
|
||||
assert (items instanceof Array)
|
||||
|
||||
log ('fetched', items.length.toString ().green, 'ledger items')
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
testLedgerItem (exchange, items[i], code, now)
|
||||
if (i > 0) {
|
||||
assert (items[i].timestamp >= items[i - 1].timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
if (exchange.has.fetchLedgerItem) {
|
||||
let { id } = items.pop ()
|
||||
let item = await exchange.fetchLedgerItem (id)
|
||||
if (Array.isArray (item)) {
|
||||
item = item[0]
|
||||
}
|
||||
testLedgerItem (exchange, item, code, now)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching ledger items not supported')
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testMarket = require ('./test.market.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'bitforex',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchMarkets...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchMarkets) {
|
||||
|
||||
// log ('fetching markets...')
|
||||
|
||||
const method = 'fetchMarkets'
|
||||
const markets = await exchange[method] ()
|
||||
Object.values (markets).forEach (market => testMarket (exchange, market, method))
|
||||
return markets
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching markets not supported')
|
||||
}
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTrade = require ('./test.trade.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'bitso',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchMyTrades...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchMyTrades) {
|
||||
|
||||
// log ('fetching my trades...')
|
||||
|
||||
const since = exchange.milliseconds () - 60 * 60 * 1000
|
||||
|
||||
let trades = await exchange.fetchMyTrades (symbol, since)
|
||||
|
||||
assert (trades instanceof Array)
|
||||
|
||||
log ('fetched', trades.length.toString ().green, 'trades')
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < trades.length; i++) {
|
||||
testTrade (exchange, trades[i], symbol, now)
|
||||
if (i > 0) {
|
||||
assert (trades[i].timestamp >= trades[i - 1].timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
// trades.forEach (trade => log.dim ('-'.repeat (80), "\n", trade))
|
||||
// log (asTable (trades))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching my trades not supported')
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOHLCV = require ('./test.ohlcv.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'btcalpha', // issue with 404 on a documented endpoint https://travis-ci.org/ccxt/ccxt/builds/643930431#L2213
|
||||
'bitmex', // an issue with null values,to be resolved later
|
||||
'cex',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchOHLCV...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchOHLCV) {
|
||||
|
||||
const timeframe = Object.keys (exchange.timeframes || { '1d': '1d' })[0]
|
||||
const limit = 10
|
||||
const duration = exchange.parseTimeframe (timeframe)
|
||||
const since = exchange.milliseconds () - duration * limit * 1000 - 1000
|
||||
|
||||
// log (symbol.green, 'fetching OHLCV...')
|
||||
|
||||
const ohlcvs = await exchange.fetchOHLCV (symbol, timeframe, since, limit)
|
||||
|
||||
const now = Date.now ()
|
||||
|
||||
for (let i = 0; i < ohlcvs.length; i++) {
|
||||
const ohlcv = ohlcvs[i]
|
||||
testOHLCV (exchange, ohlcv, symbol, now)
|
||||
}
|
||||
|
||||
log (symbol.green, 'fetched', Object.keys (ohlcvs).length.toString ().green, 'OHLCVs')
|
||||
|
||||
return ohlcvs
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching OHLCV not supported')
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOrder = require ('./test.order.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
if (exchange.has.fetchOpenOrders) {
|
||||
|
||||
// log ('fetching open orders...')
|
||||
|
||||
let orders = await exchange.fetchOpenOrders (symbol)
|
||||
|
||||
assert (orders instanceof Array)
|
||||
|
||||
log ('fetched', orders.length.toString ().green, 'open orders')
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
let order = orders[i]
|
||||
testOrder (exchange, order, symbol, now)
|
||||
assert (order.status === 'open')
|
||||
}
|
||||
|
||||
// log (asTable (orders))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching open orders not supported')
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOrderBook = require ('./test.orderbook.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
// log (symbol.green, 'fetching order book...')
|
||||
|
||||
const method = 'fetchOrderBook'
|
||||
|
||||
if (exchange.has[method]) {
|
||||
|
||||
let orderbook = await exchange[method] (symbol)
|
||||
|
||||
testOrderBook (exchange, orderbook, method, symbol)
|
||||
|
||||
return orderbook
|
||||
|
||||
} else {
|
||||
|
||||
log (method + '() not supported')
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOrderBook = require ('./test.orderbook.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
const randomSymbols = exchange.symbols.slice ().sort (() => 0.5 - Math.random ()).slice (0, 2)
|
||||
const customExchangeParams = ([
|
||||
'yobit',
|
||||
'tidex',
|
||||
'ccex',
|
||||
'liqui',
|
||||
]).reduce ((params, id) => ({ ...params, [id]: [randomSymbols], }), {})
|
||||
|
||||
const args = (exchange.id in customExchangeParams) ? customExchangeParams[exchange.id] : []
|
||||
const method = 'fetchOrderBooks'
|
||||
|
||||
if (exchange.has[method]) {
|
||||
|
||||
// log ('fetching order books...')
|
||||
|
||||
let orderbooks = await exchange[method] (...args)
|
||||
|
||||
// log.green (orderbooks)
|
||||
|
||||
Object.entries (orderbooks).forEach (([symbol, orderbook]) => {
|
||||
testOrderBook (exchange, orderbook, method, symbol)
|
||||
})
|
||||
|
||||
// return orderbooks
|
||||
|
||||
} else {
|
||||
|
||||
log (method + '() not supported')
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testOrder = require ('./test.order.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'rightbtc',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchMyTrades...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchOrders) {
|
||||
|
||||
// log ('fetching orders...')
|
||||
|
||||
const orders = await exchange.fetchOrders (symbol)
|
||||
|
||||
log ('fetched', orders.length.toString ().green, 'orders, asserting each...')
|
||||
|
||||
assert (orders instanceof Array)
|
||||
|
||||
const now = Date.now ()
|
||||
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
const order = orders[i]
|
||||
testOrder (exchange, order, symbol, now)
|
||||
}
|
||||
|
||||
// log (asTable (orders))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching orders not supported')
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
if (exchange.has.fetchStatus) {
|
||||
|
||||
// log ('fetching status...')
|
||||
|
||||
const method = 'fetchStatus'
|
||||
const status = await exchange[method] ()
|
||||
|
||||
const sampleStatus = {
|
||||
'status': 'ok', // 'ok', 'shutdown', 'error', 'maintenance'
|
||||
'updated': undefined, // integer, last updated timestamp in milliseconds if updated via the API
|
||||
'eta': undefined, // when the maintenance or outage is expected to end
|
||||
'url': undefined, // a link to a GitHub issue or to an exchange post on the subject
|
||||
}
|
||||
|
||||
assert.containsAllKeys (status, sampleStatus)
|
||||
|
||||
return status
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching status not supported')
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTicker = require ('./test.ticker.js')
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const printTickerOneLiner = (ticker, method, symbol) => {
|
||||
|
||||
log (symbol.toString ().green,
|
||||
method,
|
||||
ticker['datetime'],
|
||||
'bid: ' + (ticker['bid']),
|
||||
'ask: ' + (ticker['ask']))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const method = 'fetchTicker'
|
||||
|
||||
const skippedExchanges = [
|
||||
'digifinex',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping ' + method + '...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has[method]) {
|
||||
|
||||
// log (symbol.green, 'fetching ticker...')
|
||||
|
||||
let ticker = await exchange.fetchTicker (symbol)
|
||||
|
||||
testTicker (exchange, ticker, method, symbol)
|
||||
|
||||
printTickerOneLiner (ticker, method, symbol)
|
||||
|
||||
return ticker
|
||||
|
||||
} else {
|
||||
|
||||
log (symbol.green, 'fetchTicker () not supported')
|
||||
}
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTicker = require ('./test.ticker.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'binance',
|
||||
'digifinex',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetch all tickers...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchTickers) {
|
||||
|
||||
// log ('fetching all tickers at once...')
|
||||
|
||||
const method = 'fetchTickers'
|
||||
let tickers = undefined
|
||||
|
||||
try {
|
||||
|
||||
tickers = await exchange[method] ()
|
||||
log ('fetched all', Object.keys (tickers).length.toString ().green, 'tickers')
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log ('failed to fetch all tickers, fetching multiple tickers at once...')
|
||||
tickers = await exchange[method] ([ symbol ])
|
||||
log ('fetched', Object.keys (tickers).length.toString ().green, 'tickers')
|
||||
}
|
||||
|
||||
Object.values (tickers).forEach (ticker => testTicker (exchange, ticker, method, symbol))
|
||||
return tickers
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching all tickers at once not supported')
|
||||
}
|
||||
}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTrade = require ('./test.trade.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
// 'adara',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchTrades...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchTrades) {
|
||||
|
||||
// log (symbol.green, 'fetching trades...')
|
||||
|
||||
let trades = await exchange.fetchTrades (symbol)
|
||||
assert (trades instanceof Array)
|
||||
log (symbol.green, 'fetched', Object.values (trades).length.toString ().green, 'trades')
|
||||
let now = Date.now ()
|
||||
for (let i = 0; i < trades.length; i++) {
|
||||
testTrade (exchange, trades[i], symbol, now)
|
||||
if (i > 0) {
|
||||
if (trades[i].timestamp && trades[i - 1].timestamp) {
|
||||
assert (trades[i].timestamp >= trades[i - 1].timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// log (asTable (trades))
|
||||
|
||||
} else {
|
||||
|
||||
log (symbol.green, 'fetchTrades () not supported'.yellow)
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
log (exchange.id, 'found in ignored exchanges, skipping fetchTradingFees...')
|
||||
return
|
||||
}
|
||||
|
||||
if (exchange.has.fetchTradingFees) {
|
||||
|
||||
// log ('fetching trading fees...')
|
||||
|
||||
const method = 'fetchTradingFees'
|
||||
const fees = await exchange[method] ()
|
||||
log.green ({ 'maker': fees['maker'], 'taker': fees['taker'] })
|
||||
return fees
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching trading fees not supported')
|
||||
}
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTransaction = require ('./test.transaction.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, code) => {
|
||||
|
||||
if (exchange.has.fetchTransactions) {
|
||||
|
||||
// log ('fetching transactions...')
|
||||
|
||||
let transactions = await exchange.fetchTransactions (code)
|
||||
|
||||
log ('fetched', transactions.length.toString ().green, 'transactions, asserting each...')
|
||||
|
||||
assert (transactions instanceof Array)
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < transactions.length; i++) {
|
||||
let transaction = transactions[i]
|
||||
testTransaction (exchange, transaction, code, now)
|
||||
}
|
||||
|
||||
// log (asTable (transactions))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching transactions not supported')
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
, testTransaction = require ('./test.transaction.js')
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = async (exchange, code) => {
|
||||
|
||||
if (exchange.has.fetchWithdrawals) {
|
||||
|
||||
// log ('fetching deposits...')
|
||||
|
||||
let transactions = await exchange.fetchWithdrawals (code)
|
||||
|
||||
log ('fetched', transactions.length.toString ().green, 'withdrawals, asserting each...')
|
||||
|
||||
assert (transactions instanceof Array)
|
||||
|
||||
let now = Date.now ()
|
||||
|
||||
for (let i = 0; i < transactions.length; i++) {
|
||||
let transaction = transactions[i]
|
||||
testTransaction (exchange, transaction, code, now)
|
||||
}
|
||||
|
||||
// log (asTable (transactions))
|
||||
|
||||
} else {
|
||||
|
||||
log ('fetching withdrawals not supported')
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, item, code, now) => {
|
||||
expect (item).to.be.an ('object')
|
||||
expect (item).to.have.property ('id')
|
||||
expect (typeof item.id).to.be.oneOf (['string', 'undefined'])
|
||||
expect (item).to.have.property ('direction')
|
||||
expect (item.direction).to.be.oneOf (['in', 'out'])
|
||||
expect (item).to.have.property ('account')
|
||||
expect (typeof item.account).to.be.oneOf (['string', 'undefined'])
|
||||
expect (item).to.have.property ('referenceId')
|
||||
expect (typeof item.referenceId).to.be.oneOf (['string', 'undefined'])
|
||||
expect (item).to.have.property ('referenceAccount')
|
||||
expect (typeof item.referenceAccount).to.be.oneOf (['string', 'undefined'])
|
||||
expect (item).to.have.property ('type')
|
||||
// expect (item.type).to.be.oneOf (['trade', 'transaction', 'margin', 'cashback', 'referral', 'transfer', 'fee', /* TODO: add more types here */ ])
|
||||
expect (item).to.have.property ('currency')
|
||||
expect (exchange.currencies).to.have.property (item.currency)
|
||||
expect (item).to.have.property ('amount')
|
||||
expect (typeof item.amount).to.be.oneOf (['number', 'undefined'])
|
||||
expect (item).to.have.property ('before')
|
||||
expect (typeof item.balanceBefore).to.be.oneOf (['number', 'undefined'])
|
||||
expect (item).to.have.property ('after')
|
||||
expect (typeof item.balanceAfter).to.be.oneOf (['number', 'undefined'])
|
||||
expect (item).to.have.property ('timestamp')
|
||||
expect (typeof item.timestamp).to.be.oneOf (['number', 'undefined'])
|
||||
expect (item.timestamp).to.be.gt (1230940800000)
|
||||
expect (item.timestamp).to.be.lt (now)
|
||||
expect (item).to.have.property ('datetime')
|
||||
expect (item.datetime).to.be.equal (exchange.iso8601 (item.timestamp))
|
||||
expect (item).to.have.property ('fee')
|
||||
if (item.fee !== undefined) {
|
||||
expect (item.fee).to.be.an ('object')
|
||||
expect (item.fee).to.have.property ('cost')
|
||||
expect (typeof item.fee.cost).to.be.oneOf (['number', 'undefined'])
|
||||
expect (item.fee).to.have.property ('currency')
|
||||
expect (item.fee.currency).to.be.equal (item.currency)
|
||||
}
|
||||
expect (item).to.have.property ('info').that.is.an ('object')
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, market, method) => {
|
||||
|
||||
const format = {
|
||||
'id': 'btcusd', // string literal for referencing within an exchange
|
||||
'symbol': 'BTC/USD', // uppercase string literal of a pair of currencies
|
||||
'base': 'BTC', // uppercase string, base currency, 3 or more letters
|
||||
'quote': 'USD', // uppercase string, quote currency, 3 or more letters
|
||||
//---------------------------------------------------------------------
|
||||
// commented temporarily to bring markets to consistency first
|
||||
// 'active': true, // boolean, market status
|
||||
// 'precision': { // number of decimal digits "after the dot"
|
||||
// 'price': 8, // integer
|
||||
// 'amount': 8, // integer
|
||||
// 'cost': 8, // integer
|
||||
// },
|
||||
// 'limits': { // value limits when placing orders on this market
|
||||
// 'amount': {
|
||||
// 'min': 0.01, // order amount should be > min
|
||||
// 'max': 1000, // order amount should be < max
|
||||
// },
|
||||
// 'price': {
|
||||
// 'min': 0.01, // order price should be > min
|
||||
// 'max': 1000, // order price should be < max
|
||||
// },
|
||||
// 'cost': { // order cost = price * amount
|
||||
// 'min': 0.01, // order cost should be > min
|
||||
// 'max': 1000, // order cost should be < max
|
||||
// },
|
||||
// },
|
||||
// 'info': {}, // the original unparsed market info from the exchange
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
expect (market).to.deep.include.all.keys (format)
|
||||
expect (market).to.not.have.key ('lot')
|
||||
|
||||
// expect (market['precision']['amount']).to.not.be.undefined
|
||||
// expect (market['precision']['price']).to.not.be.undefined
|
||||
|
||||
// expect (market['limits']['amount']['min']).to.not.be.undefined
|
||||
// expect (market['limits']['price']['min']).to.not.be.undefined
|
||||
// expect (market['limits']['cost']['min']).to.not.be.undefined
|
||||
|
||||
// log (market)
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, ohlcv, symbol, now) => {
|
||||
assert.isOk (ohlcv)
|
||||
assert (Array.isArray (ohlcv))
|
||||
assert (ohlcv.length >= 6)
|
||||
for (let i = 0; i < ohlcv.length; i++) {
|
||||
assert (ohlcv[i] === undefined || typeof ohlcv[i] === 'number')
|
||||
}
|
||||
|
||||
assert (ohlcv[0] > 1230940800000) // 03 Jan 2009 - first block
|
||||
assert (ohlcv[0] < 2147483648000) // 19 Jan 2038 - int32 overflows
|
||||
|
||||
assert (ohlcv[1] === undefined || ohlcv[2] === undefined || ohlcv[1] <= ohlcv[2], 'open > high! ' + (ohlcv[1].toString () + ' > ' + ohlcv[2].toString ())) // open <= high
|
||||
assert (ohlcv[3] === undefined || ohlcv[2] === undefined || ohlcv[3] <= ohlcv[2], 'low > high! ' + (ohlcv[3].toString () + ' > ' + ohlcv[2].toString ())) // low <= high
|
||||
assert (ohlcv[3] === undefined || ohlcv[4] === undefined || ohlcv[3] <= ohlcv[4], 'low > close! ' + (ohlcv[3].toString () + ' > ' + ohlcv[4].toString ())) // low <= close
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, order, symbol, now) => {
|
||||
assert.isOk (order)
|
||||
assert (typeof order.id === 'string')
|
||||
assert (typeof order.timestamp === 'number')
|
||||
assert (order.timestamp > 1230940800000) // 03 Jan 2009 - first block
|
||||
assert (order.timestamp < now)
|
||||
assert ('lastTradeTimestamp' in order)
|
||||
assert (order.datetime === exchange.iso8601 (order.timestamp))
|
||||
assert (order.status === 'open' || order.status === 'closed' || order.status === 'canceled')
|
||||
assert (order.symbol === symbol)
|
||||
assert (typeof order.type === 'string')
|
||||
assert (order.side === 'buy' || order.side === 'sell')
|
||||
assert (typeof order.price === 'number')
|
||||
assert (order.price > 0)
|
||||
assert (typeof order.amount === 'number')
|
||||
assert (order.amount >= 0)
|
||||
if (order.filled) {
|
||||
assert (typeof order.filled === 'number')
|
||||
assert (order.filled >= 0 && order.filled <= order.amount)
|
||||
}
|
||||
if (order.remaining) {
|
||||
assert (typeof order.remaining === 'number')
|
||||
assert (order.remaining >= 0 && order.remaining <= order.amount)
|
||||
}
|
||||
if (order.trades) {
|
||||
assert (order.trades instanceof Array)
|
||||
}
|
||||
if (order.fee) {
|
||||
assert (typeof order.fee.cost === 'number')
|
||||
if (order.fee.cost !== 0)
|
||||
assert (typeof order.fee.currency === 'string')
|
||||
}
|
||||
assert.isOk (order.info)
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const printOrderBookOneLiner = (orderbook, method, symbol) => {
|
||||
|
||||
const bids = orderbook.bids
|
||||
const asks = orderbook.asks
|
||||
|
||||
log (symbol.toString ().green,
|
||||
method,
|
||||
orderbook['nonce'] || orderbook['datetime'],
|
||||
bids.length, 'bids:', bids[0],
|
||||
asks.length, 'asks:', asks[0])
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, orderbook, method, symbol) => {
|
||||
|
||||
const format = {
|
||||
'bids': [],
|
||||
'asks': [],
|
||||
'timestamp': 1234567890,
|
||||
'datetime': '2017-09-01T00:00:00',
|
||||
'nonce': 134234234,
|
||||
// 'info': {},
|
||||
}
|
||||
|
||||
expect (orderbook).to.have.all.keys (format)
|
||||
|
||||
const bids = orderbook.bids
|
||||
const asks = orderbook.asks
|
||||
|
||||
for (let i = 0; i < bids.length; i++) {
|
||||
if (bids.length > (i + 1)) {
|
||||
assert (bids[i][0] >= bids[i + 1][0])
|
||||
}
|
||||
assert (typeof bids[i][0] === 'number')
|
||||
assert (typeof bids[i][1] === 'number')
|
||||
}
|
||||
|
||||
for (let i = 0; i < asks.length; i++) {
|
||||
if (asks.length > (i + 1)) {
|
||||
assert (asks[i][0] <= asks[i + 1][0])
|
||||
}
|
||||
assert (typeof asks[i][0] === 'number')
|
||||
assert (typeof asks[i][1] === 'number')
|
||||
}
|
||||
|
||||
if (![
|
||||
|
||||
'coinmarketcap',
|
||||
'xbtce',
|
||||
'upbit', // an orderbook might have a 0-price ask occasionally
|
||||
|
||||
].includes (exchange.id)) {
|
||||
|
||||
if (bids.length && asks.length)
|
||||
assert (bids[0][0] <= asks[0][0],
|
||||
`bids[0][0]: ${bids[0][0]} (of ${bids.length}); asks[0][0]:${asks[0][0]} (of ${asks.length})`)
|
||||
|
||||
}
|
||||
|
||||
printOrderBookOneLiner (orderbook, method, symbol)
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, ticker, method, symbol) => {
|
||||
|
||||
const format = {
|
||||
'symbol': 'ETH/BTC',
|
||||
'info': {},
|
||||
'timestamp': 1234567890,
|
||||
'datetime': '2017-09-01T00:00:00',
|
||||
'high': 1.234, // highest price
|
||||
'low': 1.234, // lowest price
|
||||
'bid': 1.234, // current best bid (buy) price
|
||||
'bidVolume': 1.234, // current best bid (buy) amount (may be missing or undefined)
|
||||
'ask': 1.234, // current best ask (sell) price
|
||||
'askVolume': 1.234, // current best ask (sell) amount (may be missing or undefined)
|
||||
'vwap': 1.234, // volume weighed average price
|
||||
'open': 1.234, // opening price
|
||||
'close': 1.234, // price of last trade (closing price for current period)
|
||||
'last': 1.234, // same as `close`, duplicated for convenience
|
||||
'previousClose': 1.234, // closing price for the previous period
|
||||
'change': 1.234, // absolute change, `last - open`
|
||||
'percentage': 1.234, // relative change, `(change/open) * 100`
|
||||
'average': 1.234, // average price, `(last + open) / 2`
|
||||
'baseVolume': 1.234, // volume of base currency
|
||||
'quoteVolume': 1.234, // volume of quote currency
|
||||
}
|
||||
|
||||
expect (ticker).to.have.all.keys (format)
|
||||
|
||||
const keys = [ 'datetime', 'timestamp', 'high', 'low', 'bid', 'ask', 'baseVolume', 'quoteVolume', 'vwap' ]
|
||||
|
||||
assert (!('first' in ticker), '`first` field leftover in ' + exchange.id)
|
||||
assert (ticker['last'] === ticker['close'], '`last` != `close` in ' + exchange.id)
|
||||
|
||||
log (ticker['datetime'], exchange.id, method, ticker['symbol'].green, ticker['last'])
|
||||
|
||||
keys.forEach (key => assert (key in ticker))
|
||||
|
||||
const { high, low, vwap, baseVolume, quoteVolume } = ticker
|
||||
|
||||
// this assert breaks QuadrigaCX sometimes... still investigating
|
||||
// if (vwap)
|
||||
// assert (vwap >= low && vwap <= high)
|
||||
|
||||
/*
|
||||
if (baseVolume && quoteVolume && high && low) {
|
||||
assert (quoteVolume >= baseVolume * low) // this assertion breaks therock
|
||||
assert (quoteVolume <= baseVolume * high)
|
||||
}
|
||||
*/
|
||||
|
||||
if (baseVolume && vwap)
|
||||
assert (quoteVolume)
|
||||
|
||||
if (quoteVolume && vwap)
|
||||
assert (baseVolume)
|
||||
|
||||
// log (symbol.green, 'ticker',
|
||||
// ticker['datetime'],
|
||||
// ... (keys.map (key =>
|
||||
// key + ': ' + ticker[key])))
|
||||
|
||||
if (![
|
||||
|
||||
'coinmarketcap',
|
||||
'xbtce',
|
||||
'coss',
|
||||
'idex',
|
||||
'mercado',
|
||||
'okex',
|
||||
'southxchange', // https://user-images.githubusercontent.com/1294454/59953532-314bea80-9489-11e9-85b3-2a711ca49aa7.png
|
||||
'bitmart',
|
||||
|
||||
].includes (exchange.id)) {
|
||||
|
||||
if (ticker['baseVolume'] || ticker['quoteVolume']) {
|
||||
if (ticker['bid'] && ticker['ask']) {
|
||||
assert (ticker['bid'] <= ticker['ask'], 'ticker bid is greater than ticker ask!')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ticker
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, trade, symbol, now) => {
|
||||
|
||||
assert.isOk (trade)
|
||||
|
||||
const sampleTrade = {
|
||||
'info': { a: 1, b: 2, c: 3 }, // the original decoded JSON as is
|
||||
'id': '12345-67890:09876/54321', // string trade id
|
||||
'timestamp': 1502962946216, // Unix timestamp in milliseconds
|
||||
'datetime': '2017-08-17 12:42:48.000', // ISO8601 datetime with milliseconds
|
||||
'symbol': 'ETH/BTC', // symbol
|
||||
'order': '12345-67890:09876/54321', // string order id or undefined/None/null
|
||||
'type': 'limit', // order type, 'market', 'limit' or undefined/None/null
|
||||
'side': 'buy', // direction of the trade, 'buy' or 'sell'
|
||||
'takerOrMaker': 'taker', // string, 'taker' or 'maker'
|
||||
'price': 0.06917684, // float price in quote currency
|
||||
'amount': 1.5, // amount of base currency
|
||||
'cost': 0.10376526, // total cost (including fees), `price * amount`
|
||||
}
|
||||
|
||||
assert.containsAllKeys (trade, sampleTrade)
|
||||
assert.hasAnyKeys (trade, [ 'fee', 'fees' ])
|
||||
|
||||
const feeKeys = [ 'cost', 'currency' ]
|
||||
|
||||
if (trade.fee !== undefined) {
|
||||
assert (typeof trade.fee === 'object')
|
||||
assert.containsAllKeys (trade.fee, feeKeys)
|
||||
}
|
||||
|
||||
if (trade.fees !== undefined) {
|
||||
assert (typeof trade.fees === 'object')
|
||||
assert (Array.isArray (trade.fees))
|
||||
trade.fees.forEach (fee => assert.containsAllKeys (fee, feeKeys))
|
||||
}
|
||||
|
||||
assert (trade.id === undefined || typeof trade.id === 'string')
|
||||
assert (typeof trade.timestamp === 'number' || trade.timestamp === undefined)
|
||||
|
||||
if (trade.timestamp) {
|
||||
assert (trade.timestamp > 1230940800000) // 03 Jan 2009 - first block
|
||||
assert (trade.timestamp < 2147483648000) // 19 Jan 2038 - int32 overflows
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
const adjustedNow = now + 60000
|
||||
|
||||
const exchangesExcludedFromTimestampCheck = [
|
||||
'coinbasepro',
|
||||
'coinbaseprime', // ... as well, probably
|
||||
'kucoin2',
|
||||
]
|
||||
|
||||
if (trade.timestamp) {
|
||||
if (!exchangesExcludedFromTimestampCheck.includes (exchange.id)) {
|
||||
assert (trade.timestamp < adjustedNow, 'trade.timestamp is greater than or equal to current time: trade: ' + exchange.iso8601 (trade.timestamp) + ' now: ' + exchange.iso8601 (now))
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
assert (trade.datetime === exchange.iso8601 (trade.timestamp))
|
||||
|
||||
const isExchangeLackingFilteringTradesBySymbol = [
|
||||
'kraken', // override for kraken and possibly other exchanges as well, can't return private trades per symbol at all
|
||||
].includes (exchange.id)
|
||||
|
||||
if (!isExchangeLackingFilteringTradesBySymbol)
|
||||
assert (trade.symbol === symbol, 'trade symbol is not equal to requested symbol: trade: ' + trade.symbol + ' reqeusted: ' + symbol)
|
||||
|
||||
assert (trade.type === undefined || typeof trade.type === 'string')
|
||||
assert (trade.side === undefined || trade.side === 'buy' || trade.side === 'sell')
|
||||
assert (trade.order === undefined || typeof trade.order === 'string')
|
||||
assert (typeof trade.price === 'number', 'trade.price is not a number')
|
||||
assert (trade.price > 0)
|
||||
assert (typeof trade.amount === 'number', 'trade.amount is not a number')
|
||||
assert (trade.amount >= 0)
|
||||
assert (trade.takerOrMaker === undefined || trade.takerOrMaker === 'taker' || trade.takerOrMaker === 'maker')
|
||||
assert.isOk (trade.info)
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = require ('ololog')
|
||||
, ansi = require ('ansicolor').nice
|
||||
, chai = require ('chai')
|
||||
, expect = chai.expect
|
||||
, assert = chai.assert
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
module.exports = (exchange, transaction, code, now) => {
|
||||
assert.isOk (transaction)
|
||||
assert (typeof transaction.id === 'string')
|
||||
assert (typeof transaction.timestamp === 'number')
|
||||
assert (transaction.timestamp > 1230940800000) // 03 Jan 2009 - first block
|
||||
assert (transaction.timestamp < now)
|
||||
assert ('updated' in transaction)
|
||||
assert ('address' in transaction)
|
||||
assert ('tag' in transaction)
|
||||
assert ('txid' in transaction)
|
||||
assert (transaction.datetime === exchange.iso8601 (transaction.timestamp))
|
||||
assert (transaction.status === 'ok' || transaction.status === 'pending' || transaction.status === 'canceled')
|
||||
assert (transaction.currency === code)
|
||||
assert (typeof transaction.type === 'string')
|
||||
assert (transaction.type === 'deposit' || transaction.type === 'withdrawal')
|
||||
assert (typeof transaction.amount === 'number')
|
||||
assert (transaction.amount >= 0)
|
||||
if (transaction.fee) {
|
||||
assert (typeof transaction.fee.cost === 'number')
|
||||
if (transaction.fee.cost !== 0) {
|
||||
assert (typeof transaction.fee.currency === 'string')
|
||||
}
|
||||
}
|
||||
assert.isOk (transaction.info)
|
||||
}
|
||||
Reference in new issue
Block a user