UNPKG

@hackape/tardis-dev

Version:

Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js

112 lines 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.computeBookSnapshots = void 0; const orderbook_1 = require("../orderbook"); exports.computeBookSnapshots = (options) => () => new BookSnapshotComputable(options); const emptyBookLevel = { price: undefined, amount: undefined }; const levelsChanged = (level1, level2) => { if (level1.amount !== level2.amount) { return true; } if (level1.price !== level2.price) { return true; } return false; }; class BookSnapshotComputable { constructor({ depth, name, interval, removeCrossedLevels, onCrossedLevelRemoved }) { this.sourceDataTypes = ['book_change']; this._bookChanged = false; this._type = 'book_snapshot'; this._lastUpdateTimestamp = new Date(-1); this._bids = []; this._asks = []; this._depth = depth; this._interval = interval; this._orderBook = new orderbook_1.OrderBook({ removeCrossedLevels, onCrossedLevelRemoved }); // initialize all bids/asks levels to empty ones for (let i = 0; i < this._depth; i++) { this._bids[i] = emptyBookLevel; this._asks[i] = emptyBookLevel; } if (name === undefined) { this._name = `${this._type}_${depth}_${interval}ms`; } else { this._name = name; } } *compute(bookChange) { if (this._hasNewSnapshot(bookChange.timestamp)) { yield this._getSnapshot(bookChange); } this._update(bookChange); // check again after the update as book snapshot with interval set to 0 (real-time) could have changed if (this._hasNewSnapshot(bookChange.timestamp)) { yield this._getSnapshot(bookChange); } } _hasNewSnapshot(timestamp) { if (this._bookChanged === false) { return false; } // report new snapshot anytime book changed if (this._interval === 0) { return true; } const currentTimestampTimeBucket = this._getTimeBucket(timestamp); const snapshotTimestampBucket = this._getTimeBucket(this._lastUpdateTimestamp); if (currentTimestampTimeBucket > snapshotTimestampBucket) { // set timestamp to end of snapshot 'interval' period this._lastUpdateTimestamp = new Date((snapshotTimestampBucket + 1) * this._interval); return true; } return false; } _update(bookChange) { this._orderBook.update(bookChange); const bidsIterable = this._orderBook.bids(); const asksIterable = this._orderBook.asks(); for (let i = 0; i < this._depth; i++) { const bidLevelResult = bidsIterable.next(); const newBid = bidLevelResult.done ? emptyBookLevel : bidLevelResult.value; if (levelsChanged(this._bids[i], newBid)) { this._bids[i] = { ...newBid }; this._bookChanged = true; } const askLevelResult = asksIterable.next(); const newAsk = askLevelResult.done ? emptyBookLevel : askLevelResult.value; if (levelsChanged(this._asks[i], newAsk)) { this._asks[i] = { ...newAsk }; this._bookChanged = true; } } this._lastUpdateTimestamp = bookChange.timestamp; } _getSnapshot(bookChange) { const snapshot = { type: this._type, symbol: bookChange.symbol, exchange: bookChange.exchange, name: this._name, depth: this._depth, interval: this._interval, bids: [...this._bids], asks: [...this._asks], timestamp: this._lastUpdateTimestamp, localTimestamp: bookChange.localTimestamp }; this._bookChanged = false; return snapshot; } _getTimeBucket(timestamp) { return Math.floor(timestamp.valueOf() / this._interval); } } //# sourceMappingURL=booksnapshot.js.map