UNPKG

hft-js

Version:

High-Frequency Trading in Node.js

150 lines 5.51 kB
"use strict"; /* * bar.ts * * Copyright (c) 2025 Xiongfei Shi * * Author: Xiongfei Shi <xiongfei.shi(a)icloud.com> * License: Apache-2.0 * * https://github.com/shixiongfei/hft.js */ var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createBarGenerator = exports.BarGenerator = void 0; var utils_js_1 = require("./utils.js"); var BarGenerator = /** @class */ (function () { function BarGenerator(symbol, maxVolume) { if (maxVolume === void 0) { maxVolume = 0; } this.receivers = []; this.symbol = symbol; this.maxVolume = maxVolume; this.shouldUpdate = 0; } Object.defineProperty(BarGenerator.prototype, "receiverCount", { get: function () { return this.receivers.length; }, enumerable: false, configurable: true }); BarGenerator.prototype.addReceiver = function (receiver) { if (!this.receivers.includes(receiver)) { if (receiver.onUpdateBar) { this.shouldUpdate += 1; } this.receivers.push(receiver); } }; BarGenerator.prototype.removeReceiver = function (receiver) { var index = this.receivers.indexOf(receiver); if (index >= 0) { if (receiver.onUpdateBar) { this.shouldUpdate -= 1; } this.receivers.splice(index, 1); } }; BarGenerator.prototype.onTick = function (tick, tape) { if (tick.symbol !== this.symbol) { return; } var date = tick.date; var time = this.maxVolume > 0 ? tick.time : Math.floor(tick.time / 100) * 100; if (this.bar) { var isFinished = this.maxVolume > 0 ? this.bar.volume >= this.maxVolume : this.bar.date !== date || this.bar.time !== time; if (isFinished) { var bar_1 = Object.freeze(this.bar); Object.freeze(bar_1.buyVolumes); Object.freeze(bar_1.sellVolumes); this.receivers.forEach(function (receiver) { return receiver.onBar(bar_1); }); this.bar = undefined; } } if (tape.volumeDelta === 0) { return; } if (!this.bar) { this.bar = this._createBar(date, time, tick); } this.bar.openInterest = tick.openInterest; this.bar.closePrice = tick.lastPrice; this.bar.highPrice = Math.max(this.bar.highPrice, tick.lastPrice); this.bar.lowPrice = Math.min(this.bar.lowPrice, tick.lastPrice); this.bar.volume += tape.volumeDelta; this.bar.amount += tape.amountDelta; switch (tape.direction) { case "up": if (tick.lastPrice in this.bar.buyVolumes) { this.bar.buyVolumes[tick.lastPrice] += tape.volumeDelta; } else { this.bar.buyVolumes[tick.lastPrice] = tape.volumeDelta; } this.bar.delta += tape.volumeDelta; break; case "down": if (tick.lastPrice in this.bar.sellVolumes) { this.bar.sellVolumes[tick.lastPrice] += tape.volumeDelta; } else { this.bar.sellVolumes[tick.lastPrice] = tape.volumeDelta; } this.bar.delta -= tape.volumeDelta; break; } if (tick.lastPrice !== this.bar.poc && tape.direction !== "none") { var tickVP = (0, utils_js_1.getBarVolume)(this.bar, tick.lastPrice); var pocVP = (0, utils_js_1.getBarVolume)(this.bar, this.bar.poc); if (tickVP > pocVP) { this.bar.poc = tick.lastPrice; } } if (this.shouldUpdate > 0) { var bar_2 = Object.freeze(__assign(__assign({}, this.bar), { buyVolumes: Object.freeze(__assign({}, this.bar.buyVolumes)), sellVolumes: Object.freeze(__assign({}, this.bar.sellVolumes)) })); this.receivers.forEach(function (receiver) { if (receiver.onUpdateBar) { receiver.onUpdateBar(bar_2, tick, tape); } }); } }; BarGenerator.prototype._createBar = function (date, time, tick) { return { symbol: this.symbol, date: date, time: time, openInterest: tick.openInterest, openPrice: tick.lastPrice, highPrice: tick.lastPrice, lowPrice: tick.lastPrice, closePrice: tick.lastPrice, volume: 0, amount: 0, delta: 0, poc: tick.lastPrice, buyVolumes: {}, sellVolumes: {}, }; }; return BarGenerator; }()); exports.BarGenerator = BarGenerator; var createBarGenerator = function (symbol, maxVolume) { if (maxVolume === void 0) { maxVolume = 0; } return new BarGenerator(symbol, maxVolume); }; exports.createBarGenerator = createBarGenerator; //# sourceMappingURL=bar.js.map