diff --git a/scripts/dxtrade-smoke.mjs b/scripts/dxtrade-smoke.mjs index 6332c03..05e79c2 100644 --- a/scripts/dxtrade-smoke.mjs +++ b/scripts/dxtrade-smoke.mjs @@ -193,17 +193,27 @@ if (CONFIRM && ORDER_ACCOUNT) { const px = pos.openPrice; const tick = inst.priceIncrement || 0.01; const far = (p) => Math.round(p / tick) * tick; + // Exactly what lib/dxtrade-class.ts sends: a closing STOP/LIMIT names + // the position, never a quantity (code 33 otherwise). const leg = (c, type, price) => ({ - account: ORDER_ACCOUNT, orderCode: c, type, instrument: symbol, quantity: pos.quantity, positionEffect: 'CLOSE', + account: ORDER_ACCOUNT, orderCode: c, type, instrument: symbol, positionEffect: 'CLOSE', positionCode: pos.positionCode, side: 'SELL', tif: 'GTC', ...(type === 'LIMIT' ? { limitPrice: price } : { stopPrice: price }), }); const group = await call('POST', `/accounts/${acct}/orders`, { body: { orders: [leg(`${code}-tp`, 'LIMIT', far(px * 1.05)), leg(`${code}-sl`, 'STOP', far(px * 0.95))], contingencyType: 'OCO' }, }); show(`native OCO group of CLOSE legs (HTTP ${group.status})`, group.data); - show('open orders now', (await call('GET', `/accounts/${acct}/orders`)).data); + if (group.status >= 400) { + // The bot's fallback: the stop on its own first, then the take-profit. + show('fallback: lone STOP CLOSE', (await call('POST', `/accounts/${acct}/orders`, { body: leg(`${code}-sl1`, 'STOP', far(px * 0.95)) }))); + show('fallback: lone LIMIT CLOSE', (await call('POST', `/accounts/${acct}/orders`, { body: leg(`${code}-tp1`, 'LIMIT', far(px * 1.05)) }))); + } + show('open orders now (the exit pair should be here)', (await call('GET', `/accounts/${acct}/orders`)).data); const del = await call('DELETE', `/accounts/${acct}/orders/${encodeURIComponent(`${code}-tp`)}`); show(`cancel without If-Match (HTTP ${del.status}; 403/412/428 means it wants one)`, del.data); + // Tradeify: every trade must be held at least 20 seconds. + console.log('holding 22 s before closing (minimum hold)…'); + await sleep(22_000); const flatten = await call('POST', `/accounts/${acct}/close`, { body: { account: ORDER_ACCOUNT, closePositions: true, cancelOrders: true } }); show(`flatten via /close (HTTP ${flatten.status})`, flatten.data); }