@melonproject/exchange-aggregator
Version:
Aggregates orderbooks across various exchanges.
72 lines (71 loc) • 2.87 kB
JavaScript
;
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const R = __importStar(require("ramda"));
const types_1 = require("./types");
const token_math_1 = require("@melonproject/token-math");
exports.isBidOrder = R.propEq('type', types_1.OrderType.BID);
exports.isAskOrder = R.propEq('type', types_1.OrderType.ASK);
exports.createOrderbook = (options, orders) => {
const asks = orders
.filter(exports.isAskOrder)
.sort(exports.sortOrders)
.reduce(exports.reduceOrderVolumes, []);
const bids = orders
.filter(exports.isBidOrder)
.sort(exports.sortOrders)
.reduce(exports.reduceOrderVolumes, []);
return {
quote: options.pair.quote,
base: options.pair.quote,
network: options.network,
asks,
bids,
};
};
exports.sortOrders = (a, b) => {
const priceA = token_math_1.toAtomic(a.trade);
const priceB = token_math_1.toAtomic(b.trade);
const difference = parseFloat(token_math_1.subtract(priceB, priceA).toString());
// Sort by volumes if prices are identical.
if (difference === 0) {
const quantityA = a.trade.base.quantity;
const quantityB = b.trade.base.quantity;
return parseFloat(token_math_1.subtract(quantityA, quantityB).toString());
}
return difference;
};
exports.reduceOrderVolumes = (carry, order, index) => {
const tokenPath = ['trade', 'base', 'token'];
const token = R.path(tokenPath, order);
const volumePath = ['trade', 'base', 'quantity'];
const volume = R.path(volumePath, order);
const previousPath = [index - 1, 'cummulative', 'quantity'];
const previous = R.pathOr(0, previousPath, carry);
const cummulative = token_math_1.add(token_math_1.createQuantity(token, volume), token_math_1.createQuantity(token, previous));
const current = Object.assign({}, order, { cummulative });
return (carry || []).concat([current]);
};
exports.reduceOrderEvents = (carry, current) => {
if (current.event === types_1.NormalizedMessageType.SNAPSHOT) {
const snapshot = current;
return carry
.filter(item => item.exchange !== snapshot.exchange)
.concat(snapshot.orders);
}
if (current.event === types_1.NormalizedMessageType.SET) {
const add = current;
return carry.filter(item => item.id !== add.id).concat([add.order]);
}
if (current.event === types_1.NormalizedMessageType.REMOVE) {
const remove = current;
return carry.filter(order => order.id !== remove.id);
}
return carry;
};