-
Notifications
You must be signed in to change notification settings - Fork 416
Closed
Description
Summary
When the system retries order placement (e.g. after failing to verify a stop-loss), there is no deduplication check. This results in multiple identical orders being placed on the exchange, creating real financial risk.
Impact (observed in Demo)
During ETHUSDT Demo trading:
- 3 duplicate stop-loss orders placed at the same price
- 3 duplicate limit orders placed at the same price
- User had to manually cancel redundant orders on Binance UI
- In a live account, duplicate stop-losses would cause overselling beyond intended position size
Root Cause
The order placement flow in CcxtBroker and the AI engine's retry logic have no guard against:
- Same-direction, same-price duplicates — Before placing an order, the system doesn't check if an equivalent order already exists
- Retry without cancel-first — When verification fails (partly due to Conditional/stop orders invisible to getOrders — broker state blind spot #90 conditional order blindness), the system retries placement without canceling the previous attempt
Suggested Fix
Add a pre-flight check before placeOrder:
async placeOrder(params: OrderParams): Promise<Order> {
// 1. Fetch all active orders for this symbol (including conditional - see #90)
const existing = await this.getAllActiveOrders(params.symbol);
// 2. Check for equivalent order (same side, same type, price within tolerance)
const duplicate = existing.find(o =>
o.side === params.side &&
o.type === params.type &&
Math.abs(o.price - params.price) / params.price < 0.001 // 0.1% tolerance
);
if (duplicate) {
log.warn(`Duplicate order detected, skipping: ${duplicate.id}`);
return duplicate; // Return existing instead of creating new
}
// 3. Proceed with placement
return this.exchange.createOrder(...);
}Severity
High — This is a live-trading-blocking bug. Duplicate stop-losses directly cause overselling, which can result in unintended short positions or margin liquidation.
Related
- Depends on Conditional/stop orders invisible to getOrders — broker state blind spot #90 (conditional order visibility) for complete fix — can't deduplicate what you can't see
- The UTA snapshot system added in beta.8 may help with post-hoc detection, but doesn't prevent the duplicate at placement time
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels