From ececad8574f467f11c30a63a8d29b36c29e868a7 Mon Sep 17 00:00:00 2001 From: direkturcrypto Date: Wed, 1 Apr 2026 10:55:19 +0700 Subject: [PATCH] fix: use 2-tick ask buffer to prevent bid crossing ask (taker race) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Between fetching the best ask and placing the GTC order, the ask can move down 1 tick — turning our bid into a marketable (taker) order, which hits Polymarket's $1 minimum notional error. Cap bid to ask - 2*tickSize instead of ask - 1*tickSize to absorb the timing race. Co-Authored-By: Claude Sonnet 4.6 --- src/services/makerRebateExecutor.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/services/makerRebateExecutor.js b/src/services/makerRebateExecutor.js index b2277bf..1d17210 100644 --- a/src/services/makerRebateExecutor.js +++ b/src/services/makerRebateExecutor.js @@ -634,7 +634,10 @@ export async function executeMakerRebateStrategy(market) { const cheapAsk = cheapSide === 'yes' ? yesAsk : noAsk; let cheapBid = roundToTick(cheapBestBid + ts, tickSize); - if (cheapAsk && cheapBid >= cheapAsk) cheapBid = roundToTick(cheapAsk - ts, tickSize); + // Cap to ask - 2 ticks (not 1) to absorb timing race between fetch and place. + // A 1-tick buffer still lets the ask move 1 tick before our order is submitted, + // turning it into a marketable (taker) order and hitting the $1 minimum. + if (cheapAsk && cheapBid >= cheapAsk - ts) cheapBid = roundToTick(cheapAsk - 2 * ts, tickSize); // Range check on cheap side if (cheapBid < MIN_PRICE || cheapBid > MAX_PRICE) { @@ -647,7 +650,7 @@ export async function executeMakerRebateStrategy(market) { const expensiveBid = roundToTick(config.makerMmMaxCombined - cheapBid, tickSize); const expensiveAsk = cheapSide === 'yes' ? noAsk : yesAsk; let expBid = expensiveBid; - if (expensiveAsk && expBid >= expensiveAsk) expBid = roundToTick(expensiveAsk - ts, tickSize); + if (expensiveAsk && expBid >= expensiveAsk - ts) expBid = roundToTick(expensiveAsk - 2 * ts, tickSize); if (expBid <= 0 || expBid >= 1) { logger.info(`MakerMM${tag}: waiting — ${cheapSide === 'yes' ? 'NO' : 'YES'} bid $${expBid.toFixed(3)} out of bounds`);