futu-sdk
Version:
futu-api 的高性能精简易用版;基于*.proto静态编译,提供高性能的多层封装但层层开放的易用接口,获取最原始最完整的量化数据;相较于Python, nodejs更接近Web, 从而轻而易举搭建一个可视化交易站点,这是进行可控量化交易的不二选择。
61 lines (46 loc) • 2.23 kB
text/typescript
const FUTU_SIGN = 'ft-v1.0';
let nextSession = 1;
// 全局 TextEncoder/Decoder(浏览器和 Node.js 都支持)
const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
export const encodeBuffer = (cmd: number, protobuf: Uint8Array) => {
const session = nextSession++;
const signBytes = textEncoder.encode(FUTU_SIGN); // "ft-v1.0" → Uint8Array
// 总长度 = 8 (sign) + 4 (cmd) + 8 (session) + protobuf.length
const totalLength = 8 + 4 + 8 + protobuf.byteLength;
const buffer = new ArrayBuffer(totalLength);
const view = new Uint8Array(buffer);
const dv = new DataView(buffer);
// 1. 写入签名(最多 8 字节,不足补 0)
view.set(signBytes, 0);
for (let i = signBytes.length; i < 8; i++) {
view[i] = 0;
}
// 2. 写入 cmd (uint32, big-endian)
dv.setUint32(8, cmd, false); // false = big-endian
// 3. 写入 session (uint64, big-endian)
// 注意:JavaScript number 是 double,但 session 是整数且 <= Number.MAX_SAFE_INTEGER
// 如果 session 可能 > 2^53-1,请改用 BigInt 并分高低位写入
dv.setBigUint64(12, BigInt(session), false);
// 4. 写入 protobuf
view.set(protobuf, 20); // 8+4+8 = 20
return { message: buffer, session };
};
export const decodeBuffer = (arrayBuffer: ArrayBuffer) => {
const dv = new DataView(arrayBuffer);
const view = new Uint8Array(arrayBuffer);
const cmd = dv.getUint32(8, false);
// 1. 读取 session (uint64 @ offset 12)
const session = Number(dv.getBigUint64(12, false));
// 2. 读取 errorCode (int32 @ offset 20)
const errorCode = dv.getInt32(20, false);
// 3. 读取 errorMessage (20 bytes from offset 24)
const errorMessageBytes = view.subarray(24, 44);
// 移除末尾的 \0(找到第一个 0 或取全部)
const nullIndex = errorMessageBytes.indexOf(0);
const cleanBytes = nullIndex === -1 ? errorMessageBytes : errorMessageBytes.subarray(0, nullIndex);
const errorMessage = cleanBytes.length > 0 ? textDecoder.decode(cleanBytes) : '';
// 4. 读取 protobuf (from offset 44 to end)
const protobuf = view.subarray(44).slice(); // slice() 创建新副本(可选)
return { session, cmd, message: { errorCode, errorMessage, protobuf } };
};