UNPKG

nodejs-order-book

Version:

Node.js Lmit Order Book for high-frequency trading (HFT).

80 lines (79 loc) 3.37 kB
"use strict"; 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;