hft-js
Version:
High-Frequency Trading in Node.js
217 lines • 8.15 kB
JavaScript
;
/*
* 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
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var node_fs_1 = __importDefault(require("node:fs"));
var node_process_1 = require("node:process");
var hft = __importStar(require("."));
var existsFile = function (filename) {
try {
node_fs_1.default.accessSync(filename);
return true;
}
catch (_a) {
return false;
}
};
var config = JSON.parse(node_fs_1.default.readFileSync("test.conf.json", "utf8"));
if (!existsFile(config.FlowTdPath)) {
node_fs_1.default.mkdirSync(config.FlowTdPath, { recursive: true });
}
if (!existsFile(config.FlowMdPath)) {
node_fs_1.default.mkdirSync(config.FlowMdPath, { recursive: true });
}
var Strategy = /** @class */ (function () {
function Strategy(engine) {
this.symbol = "ni2505.SHFE";
this.engine = engine;
}
Strategy.prototype.onInit = function () {
var _this = this;
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: function (instrument) {
if (!instrument) {
console.error("Symbol", _this.symbol, "error");
(0, node_process_1.exit)(1);
}
console.log("Instrument", instrument);
},
});
this.engine.queryCommissionRate(this.symbol, {
onCommissionRate: function (rate) {
console.log("Commission Rate", rate);
},
});
this.engine.queryMarginRate(this.symbol, {
onMarginRate: function (rate) {
console.log("Margin Rate", rate);
},
});
this.engine.queryTradingAccounts({
onTradingAccounts: function (accounts) {
console.log("Trading Accounts", accounts);
},
});
this.engine.queryOrders({
onOrders: function (orders) {
console.log("Orders", orders);
},
});
this.engine.queryPositionDetails({
onPositionDetails: function (positionDetails) {
console.log("Position Details", positionDetails);
},
});
this.engine.queryPositions({
onPositions: function (positions) {
console.log("Positions", positions);
},
});
setTimeout(function () {
if (!_this.lastTick) {
console.error("Market data is not found");
return;
}
if (_this.lastBar) {
console.log(_this.lastBar);
}
_this.engine.buyOpen(_this, _this.symbol, 1, _this.lastTick.orderBook.asks.price[0], {
onPlaceOrderSent: function (receiptId) {
console.log("Open Place Order Receipt Id", receiptId);
},
onPlaceOrderError: function (reason) {
console.error("Open Place Order Error", reason);
},
});
}, 30 * 1000);
};
Strategy.prototype.onDestroy = function () {
this.engine.unsubscribeBar([this.symbol], this);
this.engine.unsubscribe([this.symbol], this);
console.log("Strategy destroy");
};
Strategy.prototype.onRisk = function (type, reason) {
console.log("Trigger Risk Control", type, reason);
};
Strategy.prototype.onEntrust = function (order) {
console.log("Entrust order", order);
};
Strategy.prototype.onTrade = function (order, trade) {
var _this = this;
console.log("Order", order, "Traded", trade);
if (order.status === "filled") {
setTimeout(function () {
_this.engine.queryPosition(_this.symbol, {
onPosition: function (position) {
if (!position || !_this.lastTick) {
return;
}
var todayLong = position.today.long.position - position.today.long.frozen;
if (todayLong > 0) {
if (_this.lastBar) {
console.log(_this.lastBar);
}
_this.engine.sellClose(_this, _this.symbol, todayLong, _this.lastTick.orderBook.bids.price[0], true, {
onPlaceOrderSent: function (receiptId) {
console.log("Close Place Order Receipt Id", receiptId);
},
onPlaceOrderError: function (reason) {
console.error("Close Place Order Error", reason);
},
});
}
},
});
}, 30 * 1000);
}
};
Strategy.prototype.onCancel = function (order) {
console.log("Cancel Order", order);
};
Strategy.prototype.onReject = function (order) {
console.log("Reject Order", order);
};
Strategy.prototype.onTick = function (tick, tape) {
//console.log(tick);
//console.log(tape);
this.lastTick = tick;
};
Strategy.prototype.onBar = function (bar) {
console.log(bar);
this.lastBar = bar;
};
return Strategy;
}());
var trader = hft.createTrader(config.FlowTdPath, config.FrontTdAddrs, config.UserInfo);
var market = hft.createMarket(config.FlowMdPath, config.FrontMdAddrs);
var enableRecorder = false;
if (enableRecorder) {
market.setRecorder({
onMarketData: function (marketData) {
console.log(marketData.InstrumentID, marketData.LastPrice);
},
}, function (instruments) {
return instruments
.filter(function (instrument) { return instrument.productType === "futures"; })
.map(function (instrument) { return instrument.symbol; });
});
}
var broker = hft.createBroker(trader, market, {
onError: function (error, message) {
console.error(error, message);
},
});
broker.addStrategy(new Strategy(broker));
if (!broker.start()) {
console.error("Broker start failed");
(0, node_process_1.exit)(1);
}
//# sourceMappingURL=index.test.js.map