nodejs-order-book
Version:
Node.js Lmit Order Book for high-frequency trading (HFT).
80 lines (79 loc) • 3.37 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StopSide = void 0;
/* node:coverage ignore next - Don't know why first and last line of each file count as uncovered */
var functional_red_black_tree_1 = __importDefault(require("functional-red-black-tree"));
var errors_1 = require("./errors");
var stopqueue_1 = require("./stopqueue");
var types_1 = require("./types");
var StopSide = /** @class */ (function () {
function StopSide(side) {
var _this = this;
this._prices = {};
// appends order to definite price level
this.append = function (order) {
var price = order.stopPrice;
var strPrice = price.toString();
if (_this._prices[strPrice] === undefined) {
var priceQueue = new stopqueue_1.StopQueue(price);
_this._prices[strPrice] = priceQueue;
_this._priceTree = _this._priceTree.insert(price, priceQueue);
}
return _this._prices[strPrice].append(order);
};
// removes order from definite price level
this.remove = function (id, stopPrice) {
var strPrice = stopPrice.toString();
if (_this._prices[strPrice] === undefined) {
throw (0, errors_1.CustomError)(errors_1.ERROR.INVALID_PRICE_LEVEL);
}
var deletedOrder = _this._prices[strPrice].remove(id);
if (_this._prices[strPrice].len() === 0) {
delete _this._prices[strPrice];
_this._priceTree = _this._priceTree.remove(stopPrice);
}
return deletedOrder;
};
this.removePriceLevel = function (priceLevel) {
delete _this._prices[priceLevel.toString()];
_this._priceTree = _this._priceTree.remove(priceLevel);
};
// Get orders queue between two price levels
this.between = function (priceBefore, marketPrice) {
var queues = [];
var lowerBound = priceBefore;
var upperBound = marketPrice;
var highest = Math.max(priceBefore, marketPrice);
var lowest = Math.min(priceBefore, marketPrice);
if (_this._side === types_1.Side.BUY) {
lowerBound = highest;
upperBound = lowest - 1;
}
else {
lowerBound = lowest;
upperBound = highest + 1;
}
_this._priceTree.forEach(function (price, queue) {
if ((_this._side === types_1.Side.BUY && price >= lowest) ||
(_this._side === types_1.Side.SELL && price <= highest)) {
queues.push(queue);
}
}, lowerBound, // Inclusive
upperBound);
return queues;
};
this.priceTree = function () {
return _this._priceTree;
};
var compare = side === types_1.Side.SELL
? function (a, b) { return a - b; }
: function (a, b) { return b - a; };
this._priceTree = (0, functional_red_black_tree_1.default)(compare);
this._side = side;
}
return StopSide;
}());
exports.StopSide = StopSide;