CLOB API (client.getOrder) can be stale — order filled on-chain but API
still shows unfilled. This caused the bot to miss fills and incorrectly
enter defensive mode or keep monitoring dead orders.
Now isOrderFilled does:
1. Check CLOB API (existing) with retry
2. Fallback: check on-chain token balance via CTF contract
If balance < 5% of original shares → treat as filled
Fixes issue where Polymarket UI shows filled but bot doesn't detect it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Orders must be cancelled BEFORE the monitoring loop can detect fills,
otherwise the limit sell at 70c can still get filled at minute 3
and trigger adaptive CL instead of defensive pivot.
Now: timeout reached → cancel both orders → enter defensivePivot
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check mid price first, place limit at market price (capped at mmSellPrice).
Only falls back to breakeven floor if mid price is below it.
Example: YES filled @ 70c, NO mid = 38c → sell @ 38c (not 30c breakeven)
This gives profit potential instead of always targeting breakeven.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adaptive CL now uses progressive floor lowering for 5-minute markets:
Phase 1 (>180s left): breakeven floor (e.g. 40c for 60c fill)
Phase 2 (90-180s): floor - 10c (accept small loss to escape)
Phase 3 (30-90s): floor - 20c + emergency cut if price < 10c
Phase 4 (<30s): force market sell
Key improvements:
- Standing order: immediately place limit at breakeven floor so brief
bounces get caught (don't wait for polling to detect price >= floor)
- Emergency cut: market sell immediately if price < 10c in phase 3
(market is decisive, bounce unlikely)
- Non-5m markets still use the existing fixed floor (mmAdaptiveMinCombined)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Market start = endTime - 5 minutes, so defensive triggers at exactly
120s after the market opens regardless of when the bot entered.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When neither limit sell fills within MM_DEFENSIVE_TIMEOUT (default 120s),
the bot enters defensive mode:
- Cancel both limit sells
- Wait until 30s before market close
- If worst side price < MM_DEFENSIVE_WORST_THRESHOLD (default 10c):
market sell worst side, hold best side for resolution (best ≈ 90c+)
- If worst side ≥ threshold: merge back to USDC (safe $0 P&L)
Only active for 5-minute markets (MM_DURATION=5m).
New config:
MM_DEFENSIVE_ENABLED (default true)
MM_DEFENSIVE_TIMEOUT (default 120s)
MM_DEFENSIVE_WORST_THRESHOLD (default 0.10)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- isOrderFilled: retry 2x with logging instead of silent error swallow
- Place YES/NO limit sells in parallel via Promise.all
- Market sell immediately when remaining shares < CLOB minimum (5 shares)
- Re-check on-chain balance before every limit/market sell in adaptive CL
- Separate redeemer Safe queue priority from strategy (split/merge) to reduce cross-market delays
- Cache USDC and exchange approvals in-memory to skip redundant on-chain reads
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When one leg fills, instead of immediately market-selling the unfilled
leg, enter a continuous monitoring loop that:
- Places a limit sell only when price >= minAdaptivePrice floor
(floor = mmAdaptiveMinCombined - filledLegPrice, default combined 1.20)
- Chases price upward (>2% improvement → re-place limit higher)
- Cancels limit on dip >5% or below floor, then waits for recovery
- Market-sells only as last resort when CL time is reached
New config: MM_ADAPTIVE_CL (toggle), MM_ADAPTIVE_MIN_COMBINED (floor),
MM_ADAPTIVE_MONITOR_SEC (poll interval). Legacy immediate market-sell
path preserved when MM_ADAPTIVE_CL=false.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename project to polymarket-terminal
- Add Market Maker bot (src/mm.js) with on-chain CTF split/merge/redeem via Gnosis Safe
- Add Orderbook Sniper bot (src/sniper.js) with multi-asset GTC low-price orders
- Add WebSocket watcher (src/services/wsWatcher.js) for real-time RTDS trade events
- Add terminal dashboard UI (src/ui/dashboard.js) using blessed
- Add CTF contract helpers (src/services/ctf.js) for splitPosition, mergePositions, redeemPositions
- Add mmDetector, mmExecutor, sniperDetector, sniperExecutor services
- Add simStats utility for dry-run P&L tracking
- Translate all Indonesian-language strings to professional English across all files
- Rewrite README.md in English with full setup guide, configuration reference, and architecture overview
- Rewrite AGENT.MD in English as comprehensive AI agent and developer reference
- Update package.json name, description, scripts, and keywords
Co-Authored-By: direkturcrypto <direkturcrypto.x@mail3.me>