The PolyClaw signal engine is deliberately narrow: it trades only semantically validated binary Bitcoin markets, uses only deterministic standard-library arithmetic, and produces a single confidence score per market that either clears the execution threshold or becomesDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/deniszidbaev-cmyk/polyclaw-trading/llms.txt
Use this file to discover all available pages before exploring further.
HOLD. There is no discretionary override and no model inference in the execution path. Every threshold, weight, and penalty is a named configuration value that can be audited and reproduced exactly.
Why BTC-only
The engine enforcesMARKET_QUERY = btc,bitcoin and rejects any market whose question wording cannot be deterministically mapped to a bullish-BTC or bearish-BTC outcome. Semantically ambiguous, mixed, or non-directional wording is never guessed. This constraint means the engine always knows which token to buy: on a direct “Will BTC exceed X?” question, bullish BTC maps to YES; on a “Will BTC fall below X?” question, bullish BTC maps to NO. The mapping must meet a minimum MIN_SEMANTIC_MAPPING_CONFIDENCE of 0.90.
Market data pipeline
Market discovery
The
fetch stage queries the Polymarket Gamma API at GET https://gamma-api.polymarket.com/markets/keyset with keyset pagination. Only active binary markets with Bitcoin-related question text, at least MIN_MARKET_LIQUIDITY_USD of liquidity, at least MIN_MARKET_VOLUME_24H_USD of 24-hour volume, and between MIN_MARKET_MINUTES_TO_EXPIRY (30 min) and MAX_MARKET_MINUTES_TO_EXPIRY (1 440 min) to resolution are accepted. YES and NO outcome tokens are joined by label.Price history
YES-token price history is fetched from the CLOB API at
GET https://clob.polymarket.com/prices-history. All public HTTP requests refuse redirects, enforce HTTPS with an official-host allowlist, cap response bytes at HTTP_MAX_BYTES, and never attach credentials.Candle construction
The
candles stage bins raw 1-minute-fidelity YES-token price samples into UTC-aligned 5m and 15m pseudo-OHLC candles. Open is the first sample in the bucket, close is the last, high and low are the extremes. Candle quality is scored based on missing bucket ratio, single-sample candle ratio, and flat candle ratio. A minimum of MIN_CANDLES_5M (default 30) and MIN_CANDLES_15M (default 30) complete candles is required.Technical indicators
All indicators use only the Python standard library and are computed from the sequence of completed-candle close prices (or OHLC for ATR). Theanalyze stage computes these for both the 5m execution timeframe and the 15m confirmation timeframe.
| Indicator | Implementation |
|---|---|
| EMA(8) | First observation as seed; alpha = 2 / (8 + 1) = 0.222. Recursive: ema[i] = alpha * close[i] + (1 - alpha) * ema[i-1] |
| EMA(21) | First observation as seed; alpha = 2 / (21 + 1) = 0.0909. Same recursion |
| RSI(14) | Arithmetic mean of the first 14 up/down deltas as seed; then Wilder smoothing: avg_gain += (gain - avg_gain) / 14 per bar |
| ATR(14) | TR = max(high − low, |high − prev_close|, |low − prev_close|); arithmetic mean of first 14 TRs as seed; then Wilder smoothing |
| POC | Nearest POC_BIN_SIZE price bin with the greatest public observation count. This is sample-density context, never traded-volume POC |
| Realized volatility | Population standard deviation of the latest 20 simple close-to-close returns |
The EMA spread percentage (
(EMA8 − EMA21) / EMA21) must reach or exceed MIN_EMA_SPREAD_PCT (default 0.003, i.e. 0.3%) for the 5m direction to be classified as bullish or bearish. A spread below this threshold produces a neutral direction, which blocks execution.Candle patterns
Theanalyze stage evaluates eight pattern groups on completed candles. Every threshold is a named config value; boundary comparisons are inclusive and unit-tested.
| Pattern group | Threshold |
|---|---|
| Engulfing | Current body ≥ 2.00× previous body |
| Harami | Current body ≤ 0.60× previous body |
| Tweezers | Relative extreme difference ≤ 10% |
| Morning/evening star | Third candle retraces ≥ 60%; strong ≥ 70%; middle body ≤ 40% |
| Three soldiers/crows | Exactly 3 bars; body ≥ 0.20× ATR; counter-wick ≤ 0.75× body |
| Shadow breakout | Relevant wick ≥ 1.50× ATR; close location ≥ 65% (or inverse for bearish) |
| Order-block sweep | Excursion ≥ 2%; deterministic 20-candle min/max level |
| Impulse | Body ≥ 2.00× prior 20-candle average; current candle excluded from average |
| POC context | Absolute distance ≤ 1%; contributes poc_context score component only |
_pattern_score:
| Pattern | Strength |
|---|---|
bullish_engulfing, bearish_engulfing, morning_star, evening_star | 0.90 |
three_white_soldiers, three_black_crows, bullish_order_block_sweep, bearish_order_block_sweep | 0.85 |
bullish_shadow_breakout, bearish_shadow_breakout | 0.80 |
bullish_impulse, bearish_impulse | 0.75 |
tweezer_bottom, tweezer_top | 0.70 |
bullish_harami, bearish_harami | 0.60 |
Signal score formula
Thesignal stage combines seven weighted components into a raw score, then subtracts applicable penalties and clamps to [0, 1]:
Score weights
| Component | Weight | Description |
|---|---|---|
trend | 0.25 | EMA spread magnitude and bullish/bearish reclaim |
rsi | 0.15 | RSI14 position within the configured directional window |
patterns | 0.25 | Highest compatible pattern strength + 0.05 per additional pattern |
candle_quality | 0.15 | 5m candle feed quality score |
market_quality | 0.10 | Market-level quality score (liquidity, volume, expiry) |
poc_context | 0.05 | 0.30 if price is within 1% of POC, else 0.0 |
timeframe | 0.05 | 0.90+ if 5m and 15m agree; 0.50 if 15m is neutral; 0.0 if conflict |
Default penalties
| Penalty | Value | Trigger |
|---|---|---|
contradiction | 0.35 | High-strength pattern collision, EMA/pattern conflict, or EMA/RSI conflict |
timeframe_conflict | 0.35 | 5m and 15m directions are opposite |
expiry | 0.20 | Market flagged near_expiry_market by quality check |
extreme_price | 0.15 | Market flagged extreme_yes_price by quality check |
overextension | 0.15 | Price is overextended relative to EMA8 and ATR14 |
sparsity | 0.15 | Excessive missing buckets, single-sample candles, or flat candles |
timeframe_neutral | 0.10 | 15m direction is neutral while 5m is directional |
The minimum confidence to trade is 0.72 (
MIN_EXECUTION_CONFIDENCE). Any market whose confidence falls below this threshold — after penalties — receives a HOLD signal and is written to runtime/manual_review.json with blocking reasons and a suggested action. The threshold is checked again at the validate stage and once more immediately before execution.Semantic mapping and output
After the confidence score is computed, the engine determines which Polymarket token to buy:- Direct questions (“Will BTC exceed X?”, “Will BTC be above Y?”): bullish BTC →
YES; bearish BTC →NO. - Inverse questions (“Will BTC fall below X?”, “Will BTC decrease?”, “Will BTC not exceed Y?”): bullish BTC →
NO; bearish BTC →YES. - Unsupported, mixed, or non-directional wording: never guessed — always
HOLD.
| Signal | File | Meaning |
|---|---|---|
YES | runtime/decisions.json | Buy the YES outcome token |
NO | runtime/decisions.json | Buy the NO outcome token |
HOLD | runtime/decisions.json + runtime/manual_review.json | Not executable; reasons recorded |
decision_id which is a SHA-256 hash of the canonical decision payload. This ID is used for duplicate detection at the validate and execute stages.