Files
ritmex-bot/src/core/lib/order-plan.ts
T
discountry fda6bcad1d refactor: rename Aster-prefixed universal types to clean names
- AsterOrder → Order
- AsterAccountSnapshot → AccountSnapshot
- AsterAccountPosition → AccountPosition
- AsterAccountAsset → AccountAsset
- AsterDepthLevel → DepthLevel
- AsterDepth → Depth
- AsterTicker → Ticker
- AsterKline → Kline

These types are the platform-agnostic contract used by all 8 exchanges,
not Aster-specific. Renamed across 63 files.
2026-04-06 18:11:57 +08:00

49 lines
1.4 KiB
TypeScript

import type { Order } from "../../exchanges/types";
export interface OrderTarget {
side: "BUY" | "SELL";
price: string; // 改为字符串避免精度问题
amount: number;
reduceOnly: boolean;
}
export function makeOrderPlan(
openOrders: Order[],
targets: OrderTarget[]
): { toCancel: Order[]; toPlace: OrderTarget[] } {
const unmatched = new Set(targets.map((_, idx) => idx));
const toCancel: Order[] = [];
for (const order of openOrders) {
const orderPrice = String(order.price);
const reduceOnly = order.reduceOnly === true;
const matchedIndex = targets.findIndex((target, index) => {
const targetPrice = String(target.price);
const orderPriceValue = Number(orderPrice);
const targetPriceValue = Number(targetPrice);
const priceMatches =
Number.isFinite(orderPriceValue) && Number.isFinite(targetPriceValue)
? Math.abs(orderPriceValue - targetPriceValue) <= 1e-8
: orderPrice === targetPrice;
return (
unmatched.has(index) &&
target.side === order.side &&
target.reduceOnly === reduceOnly &&
priceMatches
);
});
if (matchedIndex >= 0) {
unmatched.delete(matchedIndex);
} else {
toCancel.push(order);
}
}
const toPlace = [...unmatched]
.map((idx) => targets[idx])
.filter((t): t is OrderTarget => t !== undefined && t.amount > 1e-5);
return { toCancel, toPlace };
}