From cfc15cd3b0d8523e1a64a1ed0f27788819e81af1 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Mon, 3 Nov 2025 15:59:31 +0100 Subject: [PATCH] fix: Prevent runner positions from being below minimum order size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Problem:** When closing small runner positions (5% after TP1+TP2), the calculated size could be below Drift's minimum order size: - ETH minimum: 0.01 ETH - After TP1 (75%): 0.0025 ETH left - After TP2 (80%): 0.0005 ETH runner - Trailing stop tries to close 0.0005 ETH → ERROR: Below minimum 0.01 n8n showed: "Order size 0.0011 is below minimum 0.01" **Root Cause:** closePosition() calculated: sizeToClose = position.size * (percentToClose / 100) No validation against marketConfig.minOrderSize before submitting to Drift. **Solution:** Added minimum size check in closePosition() (lib/drift/orders.ts): 1. Calculate intended close size 2. If below minOrderSize → force 100% close instead 3. Log warning when this happens 4. Prevents Drift API rejection **Code Change:** ```typescript let sizeToClose = position.size * (params.percentToClose / 100) // If calculated size is below minimum, close 100% if (sizeToClose < marketConfig.minOrderSize) { console.log('⚠️ Calculated size below minimum - forcing 100% close') sizeToClose = position.size } ``` **Impact:** - ✅ Small runner positions close successfully - ✅ No more "below minimum" errors from Drift - Trades complete cleanly - ⚠️ Runner may close slightly earlier than intended (but better than error) **Example:** ETH runner at 0.0005 ETH → tries to close → detects <0.01 → closes entire 0.0005 ETH position at once instead of rejecting. This is the correct behavior - if the position is already too small, we should close it entirely. --- lib/drift/orders.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/drift/orders.ts b/lib/drift/orders.ts index 18cfc51..702f25a 100644 --- a/lib/drift/orders.ts +++ b/lib/drift/orders.ts @@ -468,7 +468,15 @@ export async function closePosition( } // Calculate size to close - const sizeToClose = position.size * (params.percentToClose / 100) + let sizeToClose = position.size * (params.percentToClose / 100) + + // CRITICAL FIX: If calculated size is below minimum, close 100% instead + // This prevents "runner" positions from being too small to close + if (sizeToClose < marketConfig.minOrderSize) { + console.log(`⚠️ Calculated close size ${sizeToClose.toFixed(4)} is below minimum ${marketConfig.minOrderSize}`) + console.log(` Forcing 100% close to avoid Drift rejection`) + sizeToClose = position.size // Close entire position + } console.log(`📝 Close order details:`) console.log(` Current position: ${position.size.toFixed(4)} ${position.side}`)