lamassu-server/lib/plugins/exchange/ccxt.js
2021-05-25 10:53:54 +01:00

51 lines
1.9 KiB
JavaScript

var ccxt = require('ccxt')
const coinUtils = require('../../coin-utils')
const common = require('../common/ccxt')
const kraken = require('./kraken')
const bitstamp = require('./bitstamp')
const itbit = require('./itbit')
const consts = require('./consts')
const ALL_EXCHANGES = {
kraken,
bitstamp,
itbit
}
function trade (side, account, cryptoAtoms, fiatCode, cryptoCode, exchangeName) {
try {
const exchangeConfig = ALL_EXCHANGES[exchangeName]
if (!exchangeConfig) throw Error('no exchange')
if (exchangeConfig.isConfigValid && !exchangeConfig.isConfigValid(account)) throw Error('Invalid config')
const exchange = new ccxt[exchangeName](exchangeConfig.loadConfig(account))
const symbol = common.verifyCurrencies(exchangeName, fiatCode, cryptoCode)
const precision = exchangeConfig.amountPrecision ? exchangeConfig.amountPrecision() : consts.DECIMAL_PRECISION.DEFAULT_AMOUNT
const amount = coinUtils.toUnit(cryptoAtoms, cryptoCode).toFixed(precision)
const options = exchangeConfig.loadOptions ? exchangeConfig.loadOptions(account) : {}
if (exchangeConfig.ORDER_TYPE === consts.ORDER_TYPES.MARKET) {
return exchange.createOrder(symbol, consts.ORDER_TYPES.MARKET, side, amount, null, options)
}
return exchange.fetchOrderBook(symbol)
.then(orderBook => {
const price = calculatePrice(side, amount, orderBook).toFixed(consts.DECIMAL_PRECISION.PRICE)
return exchange.createOrder(symbol, consts.ORDER_TYPES.LIMIT, side, amount, price, options)
})
} catch (e) {
return Promise.reject(e)
}
}
function calculatePrice (side, amount, orderBook) {
const book = side === 'buy' ? 'asks' : 'bids'
let collected = 0.0
for (const entry of orderBook[book]) {
collected += parseFloat(entry[1])
if (collected >= amount) return parseFloat(entry[0])
}
throw new Error('Insufficient market depth')
}
module.exports = { trade }