@hackape/tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
112 lines • 4.11 kB
JavaScript
"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