UNPKG

hft-js

Version:

High-Frequency Trading in Node.js

80 lines 3.87 kB
/* * utils.ts * * Copyright (c) 2025 Xiongfei Shi * * Author: Xiongfei Shi <xiongfei.shi(a)icloud.com> * License: Apache-2.0 * * https://github.com/shixiongfei/hft.js */ export const isValidPrice = (x) => x !== Number.MAX_VALUE && x !== 0; export const isValidVolume = (x) => x !== Number.MAX_VALUE && x !== 0; export const parseSymbol = (symbol) => { const [instrumentId = "", exchangeId = ""] = symbol.split("."); return [instrumentId, exchangeId]; }; export const getBarBuyVolume = (bar, price) => bar.buyVolumes[price] ?? 0; export const getBarSellVolume = (bar, price) => bar.sellVolumes[price] ?? 0; export const getBarVolume = (bar, price) => getBarBuyVolume(bar, price) + getBarSellVolume(bar, price); export const mergeBarData = (bars) => { if (bars.length === 0) { throw new Error("Bars is empty"); } if (bars.length === 1) { return bars[1]; } const bar = { symbol: bars[0].symbol, date: bars[0].date, time: bars[0].time, openInterest: bars[0].openInterest, openPrice: bars[0].openPrice, highPrice: bars[0].highPrice, lowPrice: bars[0].lowPrice, closePrice: bars[0].closePrice, volume: bars[0].volume, amount: bars[0].volume, delta: bars[0].delta, poc: bars[0].poc, buyVolumes: { ...bars[0].buyVolumes }, sellVolumes: { ...bars[0].sellVolumes }, }; for (let i = 1; i < bars.length; ++i) { const nextBar = bars[i]; bar.openInterest = nextBar.openInterest; bar.closePrice = nextBar.closePrice; bar.highPrice = Math.max(bar.highPrice, nextBar.highPrice); bar.lowPrice = Math.min(bar.lowPrice, nextBar.lowPrice); bar.volume += nextBar.volume; bar.amount += nextBar.amount; for (const price in nextBar.buyVolumes) { const volumeDelta = nextBar.buyVolumes[price]; bar.buyVolumes[price] = volumeDelta + (bar.buyVolumes[price] ?? 0); bar.delta += volumeDelta; const priceVP = bar.buyVolumes[price] + (bar.sellVolumes[price] ?? 0); const pocVP = getBarVolume(bar, bar.poc); if (priceVP > pocVP) { bar.poc = parseFloat(price); } } for (const price in nextBar.sellVolumes) { const volumeDelta = nextBar.sellVolumes[price]; bar.sellVolumes[price] = volumeDelta + (bar.sellVolumes[price] ?? 0); bar.delta -= volumeDelta; const priceVP = bar.sellVolumes[price] + (bar.buyVolumes[price] ?? 0); const pocVP = getBarVolume(bar, bar.poc); if (priceVP > pocVP) { bar.poc = parseFloat(price); } } } Object.freeze(bar.buyVolumes); Object.freeze(bar.sellVolumes); return Object.freeze(bar); }; export const buyOpen = (engine, strategy, symbol, volume, price, receiver, flag = "limit") => engine.placeOrder(strategy, symbol, "open", "long", volume, price, price > 0 && flag === "limit" ? "limit" : "market", receiver); export const buyClose = (engine, strategy, symbol, volume, price, isToday, receiver, flag = "limit") => engine.placeOrder(strategy, symbol, isToday ? "close-today" : "close", "long", volume, price, price > 0 && flag === "limit" ? "limit" : "market", receiver); export const sellOpen = (engine, strategy, symbol, volume, price, receiver, flag = "limit") => engine.placeOrder(strategy, symbol, "open", "short", volume, price, price > 0 && flag === "limit" ? "limit" : "market", receiver); export const sellClose = (engine, strategy, symbol, volume, price, isToday, receiver, flag = "limit") => engine.placeOrder(strategy, symbol, isToday ? "close-today" : "close", "short", volume, price, price > 0 && flag === "limit" ? "limit" : "market", receiver); //# sourceMappingURL=utils.js.map