hft-js
Version:
High-Frequency Trading in Node.js
214 lines • 8.69 kB
JavaScript
"use strict";
/*
* broker.ts
*
* Copyright (c) 2025 Xiongfei Shi
*
* Author: Xiongfei Shi <xiongfei.shi(a)icloud.com>
* License: Apache-2.0
*
* https://github.com/shixiongfei/hft.js
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBroker = exports.Broker = void 0;
var bar_js_1 = require("./bar.js");
var Broker = /** @class */ (function () {
function Broker(trader, market, errorReceiver) {
var _this = this;
this.strategies = [];
this.placeOrderRiskManagers = [];
this.cancelOrderRiskManagers = [];
this.trader = trader;
this.market = market;
this.generators = new Map();
this.marketLifecycle = {
onOpen: function () {
if (_this.market.hasRecorder()) {
_this.trader.queryInstruments({
onInstruments: function (instruments) {
if (instruments) {
_this.market.startRecorder(instruments);
}
},
});
}
_this.strategies.forEach(function (strategy) { return strategy.onInit(); });
},
onClose: function () {
_this.strategies.forEach(function (strategy) { return strategy.onDestroy(); });
_this.market.stopRecorder();
},
onError: function (error, message) {
if (errorReceiver) {
errorReceiver.onError(error, message);
}
},
};
this.traderLifecycle = {
onOpen: function () {
_this.market.open(_this.marketLifecycle);
},
onClose: function () {
_this.market.close(_this.marketLifecycle);
},
onError: function (error, message) {
if (errorReceiver) {
errorReceiver.onError(error, message);
}
},
};
}
Broker.prototype.start = function () {
return this.trader.open(this.traderLifecycle);
};
Broker.prototype.stop = function () {
return this.trader.close(this.traderLifecycle);
};
Broker.prototype.addStrategy = function (strategy) {
if (!this.strategies.includes(strategy)) {
this.strategies.push(strategy);
this.trader.addReceiver(strategy);
}
};
Broker.prototype.removeStrategy = function (strategy) {
var index = this.strategies.indexOf(strategy);
if (index < 0) {
return;
}
this.strategies.splice(index, 1);
this.trader.removeReceiver(strategy);
};
Broker.prototype.addPlaceOrderRiskManager = function (riskMgr) {
if (!this.placeOrderRiskManagers.includes(riskMgr)) {
this.placeOrderRiskManagers.push(riskMgr);
}
};
Broker.prototype.addCancelOrderRiskManager = function (riskMgr) {
if (!this.cancelOrderRiskManagers.includes(riskMgr)) {
this.cancelOrderRiskManagers.push(riskMgr);
}
};
Broker.prototype.subscribe = function (symbols, receiver) {
return this.market.subscribe(symbols, receiver);
};
Broker.prototype.unsubscribe = function (symbols, receiver) {
return this.market.unsubscribe(symbols, receiver);
};
Broker.prototype.subscribeBar = function (symbols, receiver) {
var _this = this;
symbols.forEach(function (symbol) {
var generator = _this.generators.get(symbol);
if (!generator) {
generator = (0, bar_js_1.createBarGenerator)(symbol);
_this.generators.set(symbol, generator);
_this.subscribe([symbol], generator);
}
generator.addReceiver(receiver);
});
};
Broker.prototype.unsubscribeBar = function (symbols, receiver) {
var _this = this;
symbols.forEach(function (symbol) {
var generator = _this.generators.get(symbol);
if (!generator) {
return;
}
generator.removeReceiver(receiver);
if (generator.receiverCount === 0) {
_this.unsubscribe([symbol], generator);
_this.generators.delete(symbol);
}
});
};
Broker.prototype.placeOrder = function (strategy, symbol, offset, side, volume, price, flag, receiver) {
for (var _i = 0, _a = this.placeOrderRiskManagers; _i < _a.length; _i++) {
var placeOrderRiskManager = _a[_i];
var result = placeOrderRiskManager.onPlaceOrder(symbol, offset, side, volume, price, flag);
if (typeof result === "boolean") {
if (!result) {
strategy.onRisk("place-order-risk");
receiver.onPlaceOrderError("Risk Rejected");
return;
}
}
else {
strategy.onRisk("place-order-risk", result);
receiver.onPlaceOrderError("Risk Rejected");
return;
}
}
return this.trader.placeOrder(symbol, offset, side, volume, price, flag, receiver);
};
Broker.prototype.cancelOrder = function (strategy, order, receiver) {
for (var _i = 0, _a = this.cancelOrderRiskManagers; _i < _a.length; _i++) {
var cancelOrderRiskManager = _a[_i];
var result = cancelOrderRiskManager.onCancelOrder(order);
if (typeof result === "boolean") {
if (!result) {
strategy.onRisk("cancel-order-risk");
receiver.onCancelOrderError("Risk Rejected");
return;
}
}
else {
strategy.onRisk("cancel-order-risk", result);
receiver.onCancelOrderError("Risk Rejected");
return;
}
}
return this.trader.cancelOrder(order, receiver);
};
Broker.prototype.buyOpen = function (strategy, symbol, volume, price, receiver) {
return this.placeOrder(strategy, symbol, "open", "long", volume, price, "limit", receiver);
};
Broker.prototype.buyClose = function (strategy, symbol, volume, price, isToday, receiver) {
return this.placeOrder(strategy, symbol, isToday ? "close-today" : "close", "long", volume, price, "limit", receiver);
};
Broker.prototype.sellOpen = function (strategy, symbol, volume, price, receiver) {
return this.placeOrder(strategy, symbol, "open", "short", volume, price, "limit", receiver);
};
Broker.prototype.sellClose = function (strategy, symbol, volume, price, isToday, receiver) {
return this.placeOrder(strategy, symbol, isToday ? "close-today" : "close", "short", volume, price, "limit", receiver);
};
Broker.prototype.getTradingDay = function () {
return this.trader.getTradingDay();
};
Broker.prototype.getOrderStatistics = function () {
return this.trader.getOrderStatistics();
};
Broker.prototype.getOrderStatistic = function (symbol) {
return this.trader.getOrderStatistic(symbol);
};
Broker.prototype.queryCommissionRate = function (symbol, receiver) {
return this.trader.queryCommissionRate(symbol, receiver);
};
Broker.prototype.queryMarginRate = function (symbol, receiver) {
return this.trader.queryMarginRate(symbol, receiver);
};
Broker.prototype.queryInstrument = function (symbol, receiver) {
return this.trader.queryInstrument(symbol, receiver);
};
Broker.prototype.queryPosition = function (symbol, receiver) {
return this.trader.queryPosition(symbol, receiver);
};
Broker.prototype.queryInstruments = function (receiver) {
return this.trader.queryInstruments(receiver);
};
Broker.prototype.queryTradingAccounts = function (receiver) {
return this.trader.queryTradingAccounts(receiver);
};
Broker.prototype.queryPositions = function (receiver) {
return this.trader.queryPositions(receiver);
};
Broker.prototype.queryPositionDetails = function (receiver) {
return this.trader.queryPositionDetails(receiver);
};
Broker.prototype.queryOrders = function (receiver) {
return this.trader.queryOrders(receiver);
};
return Broker;
}());
exports.Broker = Broker;
var createBroker = function (trader, market, errorReceiver) { return new Broker(trader, market, errorReceiver); };
exports.createBroker = createBroker;
//# sourceMappingURL=broker.js.map