feat: 优化订单创建和止损逻辑,确保参数处理符合交易所要求

This commit is contained in:
discountry
2025-10-09 20:18:13 +08:00
parent 6a3b842a3b
commit f991215d86
2 changed files with 26 additions and 4 deletions
+4 -3
View File
@@ -253,8 +253,7 @@ export async function placeStopLossOrder(
quantity,
triggerType: "STOP_LOSS",
};
// 部分交易所(例如 Paradex)要求 STOP_MARKET 同时提供 price 字段
params.price = params.stopPrice;
// Avoid forcing price for STOP_MARKET globally; keep this exchange-specific in gateways
await deduplicateOrders(adapter, symbol, openOrders, locks, timers, pendings, type, side, log);
lockOperating(locks, timers, pendings, type, log);
try {
@@ -296,7 +295,9 @@ export async function placeTrailingStopOrder(
symbol,
side,
type,
quantity: roundQtyDownToStep(quantity, qtyStep),
// Do not round down trailing-stop quantity to avoid underflowing small positions to zero;
// let the exchange adapter handle precise quantization.
quantity,
reduceOnly: "true",
activationPrice: roundDownToTick(activationPrice, priceTick),
callbackRate,
+22 -1
View File
@@ -778,7 +778,28 @@ export class AsterRestClient {
}
async createOrder(params: CreateOrderParams): Promise<AsterOrder> {
const payload: Record<string, unknown> = { ...params };
// Sanitize and normalize params for Aster futures API. Paradex-specific flags
// like reduceOnly/closePosition on STOP/TRAILING should not leak here.
const payload: Record<string, unknown> = {};
payload.symbol = String(params.symbol).toUpperCase();
payload.side = params.side;
payload.type = params.type;
if (params.timeInForce !== undefined) payload.timeInForce = params.timeInForce;
if (params.price !== undefined) payload.price = params.price;
if (params.stopPrice !== undefined) payload.stopPrice = params.stopPrice;
if (params.activationPrice !== undefined) payload.activationPrice = params.activationPrice;
if (params.callbackRate !== undefined) payload.callbackRate = params.callbackRate;
if (params.quantity !== undefined) payload.quantity = Math.abs(params.quantity);
// Aster rejects reduceOnly/closePosition for certain order types (e.g. STOP/TRAILING).
// Keep the behavior exchange-specific by stripping them here for Aster.
const type = String(params.type).toUpperCase();
const isStopOrTrailing = type === "STOP_MARKET" || type === "TRAILING_STOP_MARKET";
if (!isStopOrTrailing) {
if (params.reduceOnly !== undefined) payload.reduceOnly = params.reduceOnly;
if (params.closePosition !== undefined) payload.closePosition = params.closePosition;
}
const response = await this.signedRequest<any>({ path: "/fapi/v1/order", method: "POST", params: payload });
return toOrderFromRest(response);
}