mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-09 08:18:07 +00:00
feat: 增强 Lighter 适配器的账户更新逻辑,支持市场账户的实时更新和合并处理
This commit is contained in:
@@ -457,6 +457,14 @@ export class LighterGateway {
|
||||
ws.send(JSON.stringify({ type: "subscribe", channel: `order_book/${marketId}` }));
|
||||
ws.send(JSON.stringify({ type: "subscribe", channel: `account_all/${Number(this.signer.accountIndex)}` }));
|
||||
const auth = await this.ensureAuthToken();
|
||||
// Subscribe to per-market account updates to receive timely position changes
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "subscribe",
|
||||
channel: `account_market/${Number(marketId)}/${Number(this.signer.accountIndex)}`,
|
||||
auth,
|
||||
})
|
||||
);
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "subscribe",
|
||||
@@ -504,6 +512,10 @@ export class LighterGateway {
|
||||
case "update/account_all":
|
||||
this.handleAccountAll(message);
|
||||
break;
|
||||
case "subscribed/account_market":
|
||||
case "update/account_market":
|
||||
this.handleAccountMarket(message);
|
||||
break;
|
||||
case "subscribed/account_all_orders":
|
||||
case "update/account_all_orders":
|
||||
this.handleAccountOrders(message);
|
||||
@@ -566,13 +578,54 @@ export class LighterGateway {
|
||||
|
||||
private handleAccountAll(message: any): void {
|
||||
if (!message) return;
|
||||
// account_all messages may be partial updates; if positions is omitted, retain existing positions
|
||||
// account_all may be partial; merge provided markets into existing positions
|
||||
if (Object.prototype.hasOwnProperty.call(message, "positions")) {
|
||||
const positionsObject = message.positions ?? {};
|
||||
const positions: LighterPosition[] = (Array.isArray(positionsObject)
|
||||
const incoming: LighterPosition[] = (Array.isArray(positionsObject)
|
||||
? (positionsObject as LighterPosition[])
|
||||
: (Object.values(positionsObject) as LighterPosition[])) as LighterPosition[];
|
||||
this.positions = positions;
|
||||
|
||||
const byMarket = new Map<number, LighterPosition>();
|
||||
for (const p of this.positions ?? []) {
|
||||
const mid = Number(p.market_id);
|
||||
if (Number.isFinite(mid)) byMarket.set(mid, p);
|
||||
}
|
||||
for (const p of incoming) {
|
||||
const mid = Number(p.market_id);
|
||||
if (!Number.isFinite(mid)) continue;
|
||||
const sign = Number(p.sign ?? 0);
|
||||
const size = Number(p.position ?? 0);
|
||||
if (sign === 0 || Math.abs(size) < 1e-12) {
|
||||
byMarket.delete(mid);
|
||||
} else {
|
||||
byMarket.set(mid, p);
|
||||
}
|
||||
}
|
||||
this.positions = Array.from(byMarket.values());
|
||||
}
|
||||
this.emitAccount();
|
||||
}
|
||||
|
||||
private handleAccountMarket(message: any): void {
|
||||
if (!message) return;
|
||||
const position: LighterPosition | undefined = message.position as LighterPosition | undefined;
|
||||
if (!position || !Number.isFinite(Number(position.market_id))) return;
|
||||
const marketId = Number(position.market_id);
|
||||
const sign = Number(position.sign ?? 0);
|
||||
const size = Number(position.position ?? 0);
|
||||
const shouldRemove = sign === 0 || Math.abs(size) < 1e-12;
|
||||
if (shouldRemove) {
|
||||
this.positions = (this.positions ?? []).filter((p) => Number(p.market_id) !== marketId);
|
||||
} else {
|
||||
let updated = false;
|
||||
this.positions = (this.positions ?? []).map((p) => {
|
||||
if (Number(p.market_id) === marketId) {
|
||||
updated = true;
|
||||
return position;
|
||||
}
|
||||
return p;
|
||||
});
|
||||
if (!updated) this.positions.push(position);
|
||||
}
|
||||
this.emitAccount();
|
||||
}
|
||||
|
||||
@@ -172,7 +172,8 @@ function lighterPositionToAster(symbol: string, position: LighterPosition): Aste
|
||||
const sign = position.sign ?? 0;
|
||||
const positionSide = sign > 0 ? "LONG" : sign < 0 ? "SHORT" : "BOTH";
|
||||
const magnitude = Number(position.position ?? 0);
|
||||
const signed = sign < 0 ? -Math.abs(magnitude) : Math.abs(magnitude);
|
||||
// Normalize: when sign is 0, treat as flat regardless of reported magnitude
|
||||
const signed = sign === 0 ? 0 : sign < 0 ? -Math.abs(magnitude) : Math.abs(magnitude);
|
||||
return {
|
||||
symbol,
|
||||
positionAmt: Number.isFinite(signed) ? signed.toString() : position.position ?? "0",
|
||||
|
||||
Reference in New Issue
Block a user