UNPKG

hft-js

Version:

High-Frequency Trading in Node.js

177 lines 6.05 kB
/* * index.test.ts * * Copyright (c) 2025 Xiongfei Shi * * Author: Xiongfei Shi <xiongfei.shi(a)icloud.com> * License: Apache-2.0 * * https://github.com/shixiongfei/hft.js */ import process from "node:process"; import fs from "node:fs"; import * as hft from "./index.js"; const config = JSON.parse(fs.readFileSync("test.conf.json", "utf8")); class Strategy { lastTick; lastBar; engine; symbol = config.Test.Symbol; constructor(engine) { this.engine = engine; } onInit() { this.engine.subscribe([this.symbol], this); this.engine.subscribeBar([this.symbol], this); console.log("Strategy init"); console.log("Trading Day", this.engine.getTradingDay()); this.engine.queryInstrument(this.symbol, { onInstrument: (instrument) => { if (!instrument) { console.error("Symbol", this.symbol, "error"); process.exit(1); } console.log("Instrument", instrument); }, }); this.engine.queryCommissionRate(this.symbol, { onCommissionRate: (rate) => { console.log("Commission Rate", rate); }, }); this.engine.queryMarginRate(this.symbol, { onMarginRate: (rate) => { console.log("Margin Rate", rate); }, }); this.engine.queryTradingAccounts({ onTradingAccounts: (accounts) => { console.log("Trading Accounts", accounts); }, }); this.engine.queryOrders({ onOrders: (orders) => { console.log("Orders", orders); }, }); this.engine.queryPositionDetails({ onPositionDetails: (positionDetails) => { console.log("Position Details", positionDetails); }, }); this.engine.queryPositions({ onPositions: (positions) => { console.log("Positions", positions); }, }); setTimeout(() => { if (!this.lastTick) { console.error("Market data is not found"); return; } if (this.lastBar) { console.log(this.lastBar); } const price = this.lastTick.orderBook.asks.price[0]; if (!price) { console.error("Invalid price"); return; } hft.buyOpen(this.engine, this, this.symbol, 1, price, { onPlaceOrderSent: (receiptId) => { console.log("Open Place Order Receipt Id", receiptId); }, onPlaceOrderError: (reason) => { console.error("Open Place Order Error", reason); }, }); }, 30 * 1000); } onDestroy() { this.engine.unsubscribeBar([this.symbol], this); this.engine.unsubscribe([this.symbol], this); console.log("Strategy destroy"); } onRisk(type, reason) { console.log("Trigger Risk Control", type, reason); } onEntrust(order) { console.log("Entrust order", order); } onTrade(order, trade) { console.log("Order", order, "Traded", trade); if (order.status === "filled") { setTimeout(() => { this.engine.queryPosition(this.symbol, { onPosition: (position) => { if (!position || !this.lastTick) { return; } const todayLong = position.today.long.position - position.today.long.frozen; if (todayLong > 0) { if (this.lastBar) { console.log(this.lastBar); } hft.sellClose(this.engine, this, this.symbol, todayLong, 0, true, { onPlaceOrderSent: (receiptId) => { console.log("Close Place Order Receipt Id", receiptId); }, onPlaceOrderError: (reason) => { console.error("Close Place Order Error", reason); }, }); } }, }); }, 30 * 1000); } } onCancel(order) { console.log("Cancel Order", order); } onReject(order) { console.log("Reject Order", order); } onTick(tick, tape) { //console.log(tick); //console.log(tape); this.lastTick = tick; } onBar(bar) { console.log(bar); this.lastBar = bar; } } const market = hft.createMarket(config.FlowMdPath, config.FrontMdAddrs, { listener: { onSubscribed: (symbol) => { console.log(`Market subscribed: ${symbol}`); }, onUnsubscribed: (symbol) => { console.log(`Market unsubscribed: ${symbol}`); }, }, }); const trader = hft.createTrader(config.FlowTdPath, config.FrontTdAddrs, config.UserInfo, { fastQueryLastTick: (instrumentId) => market.getLastTick(instrumentId) }); const recorder = market.getRecorder(); const enableRecorder = false; if (enableRecorder && recorder) { recorder.setRecorder({ onMarketData: (marketData) => { console.log(marketData.InstrumentID, marketData.LastPrice); }, }, (instruments) => instruments .filter((instrument) => instrument.productType === "futures") .map((instrument) => instrument.symbol)); } const broker = hft.createBroker(trader, market, { onError(error, message) { console.error(error, message); }, }); broker.addStrategy(new Strategy(broker)); if (!broker.start()) { console.error("Broker start failed"); process.exit(1); } //# sourceMappingURL=index.test.js.map