mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 17:28:08 +00:00
feat: 优化平仓订单逻辑,避免在止损订单中下调数量,确保精确传递给交易所
This commit is contained in:
@@ -249,7 +249,8 @@ export async function placeStopLossOrder(
|
|||||||
reduceOnly: "true",
|
reduceOnly: "true",
|
||||||
closePosition: "true",
|
closePosition: "true",
|
||||||
timeInForce: "GTC",
|
timeInForce: "GTC",
|
||||||
quantity: roundQtyDownToStep(quantity, qtyStep),
|
// Do not round down stop quantity here to avoid underflow to exchange min; gateway will quantize precisely
|
||||||
|
quantity,
|
||||||
triggerType: "STOP_LOSS",
|
triggerType: "STOP_LOSS",
|
||||||
};
|
};
|
||||||
// 部分交易所(例如 Paradex)要求 STOP_MARKET 同时提供 price 字段
|
// 部分交易所(例如 Paradex)要求 STOP_MARKET 同时提供 price 字段
|
||||||
|
|||||||
@@ -566,8 +566,7 @@ export class ParadexGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normalize amount for Paradex according to market precision/limits.
|
// Normalize amount for Paradex according to market precision/limits.
|
||||||
// Particularly important for STOP_MARKET closePosition orders where rounding
|
// For STOP_MARKET closePosition orders, prefer using the current position size.
|
||||||
// upstream may result in 0 due to larger strategy qtyStep.
|
|
||||||
try {
|
try {
|
||||||
const market = typeof (this.exchange as any).market === "function"
|
const market = typeof (this.exchange as any).market === "function"
|
||||||
? (this.exchange as any).market(symbol)
|
? (this.exchange as any).market(symbol)
|
||||||
@@ -577,9 +576,13 @@ export class ParadexGateway {
|
|||||||
// Only trust explicit exchange min limit; do NOT infer 1 from precision=0
|
// Only trust explicit exchange min limit; do NOT infer 1 from precision=0
|
||||||
const minAmount = Number.isFinite(limitMin) && limitMin > 0 ? limitMin : undefined;
|
const minAmount = Number.isFinite(limitMin) && limitMin > 0 ? limitMin : undefined;
|
||||||
|
|
||||||
// If closePosition is requested and amount is missing or too small, bump to minimum allowed
|
// If closePosition is requested and amount is missing or too small, prefer using current position size
|
||||||
const isClosePosition = (extraParams as any).closePosition === true;
|
const isClosePosition = (extraParams as any).closePosition === true;
|
||||||
if (isClosePosition) {
|
if (isClosePosition) {
|
||||||
|
const posAbs = this.getCurrentPositionAbs();
|
||||||
|
if (Number.isFinite(posAbs) && posAbs > 0) {
|
||||||
|
amount = posAbs;
|
||||||
|
}
|
||||||
const current = Number(amount);
|
const current = Number(amount);
|
||||||
if (!Number.isFinite(current) || current <= 0 || (minAmount !== undefined && current < minAmount)) {
|
if (!Number.isFinite(current) || current <= 0 || (minAmount !== undefined && current < minAmount)) {
|
||||||
amount = (minAmount as number) ?? 1e-5; // fallback if market data is missing
|
amount = (minAmount as number) ?? 1e-5; // fallback if market data is missing
|
||||||
@@ -615,6 +618,16 @@ export class ParadexGateway {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getCurrentPositionAbs(): number | undefined {
|
||||||
|
const snapshot = this.lastBalanceSnapshot;
|
||||||
|
if (!snapshot) return undefined;
|
||||||
|
const pos = (snapshot.positions || []).find((p) => p.symbol === this.displaySymbol);
|
||||||
|
if (!pos) return undefined;
|
||||||
|
const amt = Number(pos.positionAmt);
|
||||||
|
if (!Number.isFinite(amt)) return undefined;
|
||||||
|
return Math.abs(amt);
|
||||||
|
}
|
||||||
|
|
||||||
async cancelOrder(params: { symbol: string; orderId: number | string }): Promise<void> {
|
async cancelOrder(params: { symbol: string; orderId: number | string }): Promise<void> {
|
||||||
await this.ensureInitialized(params.symbol);
|
await this.ensureInitialized(params.symbol);
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user