feat: 重构订单路由逻辑,添加订单意图类型以支持多交易所订单处理

This commit is contained in:
discountry
2025-10-23 14:04:44 +08:00
parent fabc8af679
commit ea5da20311
10 changed files with 745 additions and 62 deletions
+118
View File
@@ -0,0 +1,118 @@
import type { ExchangeAdapter } from "./adapter";
import type { AsterOrder } from "./types";
import type {
BaseOrderIntent,
ClosePositionIntent,
LimitOrderIntent,
MarketOrderIntent,
StopOrderIntent,
TrailingStopOrderIntent,
} from "./order-schema";
import * as asterOrders from "./aster/order";
import * as backpackOrders from "./backpack/order";
import * as grvtOrders from "./grvt/order";
import * as lighterOrders from "./lighter/order";
import * as paradexOrders from "./paradex/order";
type ExchangeKey = "aster" | "backpack" | "grvt" | "lighter" | "paradex";
interface ExchangeOrderHandlers {
limit(intent: LimitOrderIntent): Promise<AsterOrder>;
market(intent: MarketOrderIntent): Promise<AsterOrder>;
stop(intent: StopOrderIntent): Promise<AsterOrder>;
trailingStop?: (intent: TrailingStopOrderIntent) => Promise<AsterOrder>;
close(intent: ClosePositionIntent): Promise<AsterOrder>;
}
const handlerMap: Record<ExchangeKey, ExchangeOrderHandlers> = {
aster: {
limit: asterOrders.createLimitOrder,
market: asterOrders.createMarketOrder,
stop: asterOrders.createStopOrder,
trailingStop: asterOrders.createTrailingStopOrder,
close: asterOrders.createClosePositionOrder,
},
backpack: {
limit: backpackOrders.createLimitOrder,
market: backpackOrders.createMarketOrder,
stop: backpackOrders.createStopOrder,
trailingStop: backpackOrders.createTrailingStopOrder,
close: backpackOrders.createClosePositionOrder,
},
grvt: {
limit: grvtOrders.createLimitOrder,
market: grvtOrders.createMarketOrder,
stop: grvtOrders.createStopOrder,
trailingStop: grvtOrders.createTrailingStopOrder,
close: grvtOrders.createClosePositionOrder,
},
lighter: {
limit: lighterOrders.createLimitOrder,
market: lighterOrders.createMarketOrder,
stop: lighterOrders.createStopOrder,
trailingStop: lighterOrders.createTrailingStopOrder,
close: lighterOrders.createClosePositionOrder,
},
paradex: {
limit: paradexOrders.createLimitOrder,
market: paradexOrders.createMarketOrder,
stop: paradexOrders.createStopOrder,
trailingStop: paradexOrders.createTrailingStopOrder,
close: paradexOrders.createClosePositionOrder,
},
};
const knownExchanges: ExchangeKey[] = ["aster", "backpack", "grvt", "lighter", "paradex"];
function normalizeExchangeId(value: string | undefined | null): string | undefined {
if (!value) return undefined;
return value.trim().toLowerCase();
}
function resolveExchangeKey(adapter: ExchangeAdapter): ExchangeKey {
const fromEnv = normalizeExchangeId(process.env.TRADE_EXCHANGE ?? process.env.EXCHANGE);
const candidates = [fromEnv, normalizeExchangeId(adapter.id)];
for (const candidate of candidates) {
if (!candidate) continue;
if ((knownExchanges as string[]).includes(candidate)) {
return candidate as ExchangeKey;
}
}
throw new Error(
`Unsupported exchange for order routing: ${candidates.filter(Boolean).join(", ") || "unknown"}`
);
}
function getHandlers(intent: BaseOrderIntent): ExchangeOrderHandlers {
const exchangeKey = resolveExchangeKey(intent.adapter);
const handlers = handlerMap[exchangeKey];
if (!handlers) {
throw new Error(`Order handlers not implemented for exchange: ${exchangeKey}`);
}
return handlers;
}
export function routeLimitOrder(intent: LimitOrderIntent): Promise<AsterOrder> {
return getHandlers(intent).limit(intent);
}
export function routeMarketOrder(intent: MarketOrderIntent): Promise<AsterOrder> {
return getHandlers(intent).market(intent);
}
export function routeStopOrder(intent: StopOrderIntent): Promise<AsterOrder> {
return getHandlers(intent).stop(intent);
}
export function routeTrailingStopOrder(intent: TrailingStopOrderIntent): Promise<AsterOrder> {
const handlers = getHandlers(intent);
if (!handlers.trailingStop) {
throw new Error("Trailing stop orders are not supported by the current exchange");
}
return handlers.trailingStop(intent);
}
export function routeCloseOrder(intent: ClosePositionIntent): Promise<AsterOrder> {
return getHandlers(intent).close(intent);
}