How Polymarket Crypto Market Discovery Handles Timing Gates for Different Durations
Polymarket crypto market discovery uses the MarketScanner component in src/strategies/crypto-hft/market-scanner.ts to enforce dual timing gates—minRoundAgeSec and minTimeLeftSec—that dynamically adapt to any market duration by calculating round slots based on Unix timestamps.
Polymarket crypto market discovery in the CloddsBot repository relies on a sophisticated round-based scanning system that prevents trading during volatile opening periods or unsafe closing windows. The implementation centers on the MarketScanner class, which continuously monitors Gamma API markets across multiple durations—from 5-minute to daily contracts—while applying configurable timing constraints that scale automatically with each round length.
Core Architecture of the MarketScanner
The MarketScanner class serves as the central discovery engine for crypto High-Frequency Trading (HFT) strategies. Located in src/strategies/crypto-hft/market-scanner.ts, it bridges the Polymarket Gamma API with the trading engine by calculating temporal slots and filtering markets through strict timing validations.
Round-Based Slot Tracking
At the heart of the discovery system lies slot calculation. The scanner determines the current slot by dividing the Unix timestamp by the configured roundDurationSec:
// Conceptual implementation based on slot logic (lines 54-60)
const currentSlot = Math.floor(Date.now() / 1000 / config.roundDurationSec);
This slot calculation defines the market's expiry window and groups contracts belonging to the same trading round. Because the slot is derived from the configurable roundDurationSec, the same logic applies seamlessly whether tracking 5-minute binary options or daily prediction markets.
Duration Mapping for Polymarket Gamma API
Before querying the API, the scanner translates internal duration configurations into Polymarket's URL slug fragments. A static durationMap in src/strategies/crypto-hft/market-scanner.ts (lines 84-90) converts supported durations—5 minutes, 15 minutes, 1 hour, 4 hours, and daily—into their corresponding Gamma API identifiers:
- 5 minutes: Maps to Polymarket's short-term contract slug format
- 15 minutes: Mid-frequency trading identifier
- 1 hour / 4 hours: Standard hourly range formats
- Daily: Long-term contract grouping
This mapping ensures that fetchMarkets() constructs the correct deterministic query for each duration tier.
How Timing Gates Filter Markets
The canTrade() method implements the timing gate logic that protects the trading engine from entering positions during suboptimal market conditions. Two runtime constraints, defined in the CryptoHftConfig interface (src/strategies/crypto-hft/types.ts), govern market eligibility:
The minRoundAgeSec Gate (Early Round Protection)
Markets are explicitly blocked during the initial volatile phase of each round. The minRoundAgeSec parameter defines how many seconds must elapse after a round begins before trading is permitted:
// Timing gate check (lines 80-82)
if (roundAgeSec < config.minRoundAgeSec) {
return { ok: false, reason: 'Round too young' };
}
This prevents the algorithm from capturing spreads during the chaotic opening moments when liquidity is still establishing.
The minTimeLeftSec Gate (Expiry Protection)
Conversely, the minTimeLeftSec gate rejects markets approaching resolution. This safety mechanism prevents last-second trades that carry heightened settlement risk:
// Expiry protection check (lines 83-85)
if (timeLeftSec < config.minTimeLeftSec) {
return { ok: false, reason: 'Too close to expiry' };
}
Together, these gates create a trading window that only admits markets sufficiently mature yet comfortably distant from expiration.
Adaptive Logic Across Durations
Because both thresholds are expressed in absolute seconds rather than percentages, they adapt automatically to any market duration configured in presets.ts. A 5-minute market might use minRoundAgeSec: 30 (30 seconds), while a daily market might use minRoundAgeSec: 300 (5 minutes), yet both utilize the exact same validation logic in canTrade().
The 10-Second Refresh Cycle
The scanner maintains market freshness through a periodic refresh cycle triggered every 10 seconds. This loop, implemented in the main scanner logic (lines 31-34), performs three critical functions:
- Slot Change Detection: Monitors for round transitions by comparing the previous and current slot calculations
- Rate Limiting: Prevents Gamma API spam by enforcing cooldown periods between manual refreshes
- Market Hydration: Calls
fetchMarkets()to retrieve contracts matching thedurationLabeland current timing constraints
When fetchMarkets() executes, it first attempts a deterministic slug query based on the asset symbol and current slot, then falls back to a generic search if the specific contract is not yet indexed. Both paths respect the active timing gates.
Configuring Timing Gates via Strategy Presets
All timing parameters reside within CryptoHftConfig, with practical implementations demonstrated in src/strategies/crypto-hft/presets.ts (lines 95-332). These presets demonstrate how different strategies tune gates for various durations:
import { createMarketScanner } from './strategies/crypto-hft/market-scanner';
import { preset15m } from './strategies/crypto-hft/presets';
// Initialize scanner with 15-minute duration configuration
const scanner = createMarketScanner(preset15m);
// Start the automatic refresh loop
scanner.start();
// Check if trading is permitted under current timing constraints
const tradeStatus = scanner.canTrade();
if (!tradeStatus.ok) {
console.log('Trading blocked:', tradeStatus.reason);
}
For manual testing or debugging, developers can trigger immediate refreshes:
// Force market refresh bypassing the 10-second timer
const markets = await scanner.refresh();
console.log(`Discovered ${markets.length} valid markets`);
Summary
- Polymarket crypto market discovery centers on the
MarketScannerclass insrc/strategies/crypto-hft/market-scanner.ts, which calculates temporal slots based on configurableroundDurationSecvalues. - Dual timing gates—
minRoundAgeSecandminTimeLeftSec—prevent trading during volatile opening periods and unsafe pre-expiry windows by validating round age and remaining time incanTrade(). - Duration mapping uses a static map to translate internal duration configurations (5m, 15m, 1h, 4h, daily) into Polymarket Gamma API slugs.
- Adaptive validation allows the same timing gate logic to function across all market durations because constraints are expressed in seconds relative to the current round.
- 10-second refresh cycles continuously hydrate market data while respecting rate limits and timing constraints defined in
CryptoHftConfig.
Frequently Asked Questions
What is the purpose of minRoundAgeSec in Polymarket trading?
The minRoundAgeSec parameter prevents the trading engine from entering positions during the initial seconds of a new round when bid-ask spreads are typically widest and most volatile. By requiring a minimum number of seconds to elapse after the round timestamp, the scanner ensures liquidity has stabilized before risking capital.
How does the MarketScanner handle different market durations like 5-minute vs hourly?
The scanner uses the same slot calculation logic for all durations by dividing the Unix timestamp by the configurable roundDurationSec. A static durationMap translates these configurations into Polymarket-specific API slugs, while the timing gates (minRoundAgeSec and minTimeLeftSec) scale appropriately because they are defined in absolute seconds within each duration's preset configuration.
Where are the timing gate thresholds configured in CloddsBot?
Timing thresholds are defined in the CryptoHftConfig interface located in src/strategies/crypto-hft/types.ts and instantiated through strategy presets in src/strategies/crypto-hft/presets.ts. Each preset (e.g., preset5m, preset1h) specifies unique values for minRoundAgeSec and minTimeLeftSec optimized for that duration's volatility profile.
Why does the scanner refresh every 10 seconds?
The 10-second refresh interval balances market data freshness with API rate limiting constraints. This period allows the MarketScanner to detect new rounds (slot changes) and expired markets quickly while avoiding excessive requests to the Polymarket Gamma API, which could trigger IP throttling or bans.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →