Skip to main content

Documentation 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.

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 becomes 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 enforces MARKET_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

1

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.
2

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.
3

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). The analyze stage computes these for both the 5m execution timeframe and the 15m confirmation timeframe.
IndicatorImplementation
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
POCNearest POC_BIN_SIZE price bin with the greatest public observation count. This is sample-density context, never traded-volume POC
Realized volatilityPopulation 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

The analyze stage evaluates eight pattern groups on completed candles. Every threshold is a named config value; boundary comparisons are inclusive and unit-tested.
Pattern groupThreshold
EngulfingCurrent body ≥ 2.00× previous body
HaramiCurrent body ≤ 0.60× previous body
TweezersRelative extreme difference ≤ 10%
Morning/evening starThird candle retraces ≥ 60%; strong ≥ 70%; middle body ≤ 40%
Three soldiers/crowsExactly 3 bars; body ≥ 0.20× ATR; counter-wick ≤ 0.75× body
Shadow breakoutRelevant wick ≥ 1.50× ATR; close location ≥ 65% (or inverse for bearish)
Order-block sweepExcursion ≥ 2%; deterministic 20-candle min/max level
ImpulseBody ≥ 2.00× prior 20-candle average; current candle excluded from average
POC contextAbsolute distance ≤ 1%; contributes poc_context score component only
Each detected pattern carries a fixed strength score used in _pattern_score:
PatternStrength
bullish_engulfing, bearish_engulfing, morning_star, evening_star0.90
three_white_soldiers, three_black_crows, bullish_order_block_sweep, bearish_order_block_sweep0.85
bullish_shadow_breakout, bearish_shadow_breakout0.80
bullish_impulse, bearish_impulse0.75
tweezer_bottom, tweezer_top0.70
bullish_harami, bearish_harami0.60
A compatible candle pattern (one whose direction matches the EMA direction) is mandatory for execution. A lone harami, a high-strength pattern collision between bullish and bearish, or a strongest incompatible pattern stronger than the strongest compatible pattern will each add a blocking reason.

Signal score formula

The signal stage combines seven weighted components into a raw score, then subtracts applicable penalties and clamps to [0, 1]:
raw_score =
    trend          * 0.25 +
    rsi            * 0.15 +
    patterns       * 0.25 +
    candle_quality * 0.15 +
    market_quality * 0.10 +
    poc_context    * 0.05 +
    timeframe      * 0.05

confidence = clamp(raw_score - sum(penalties), 0, 1)

Score weights

ComponentWeightDescription
trend0.25EMA spread magnitude and bullish/bearish reclaim
rsi0.15RSI14 position within the configured directional window
patterns0.25Highest compatible pattern strength + 0.05 per additional pattern
candle_quality0.155m candle feed quality score
market_quality0.10Market-level quality score (liquidity, volume, expiry)
poc_context0.050.30 if price is within 1% of POC, else 0.0
timeframe0.050.90+ if 5m and 15m agree; 0.50 if 15m is neutral; 0.0 if conflict

Default penalties

PenaltyValueTrigger
contradiction0.35High-strength pattern collision, EMA/pattern conflict, or EMA/RSI conflict
timeframe_conflict0.355m and 15m directions are opposite
expiry0.20Market flagged near_expiry_market by quality check
extreme_price0.15Market flagged extreme_yes_price by quality check
overextension0.15Price is overextended relative to EMA8 and ATR14
sparsity0.15Excessive missing buckets, single-sample candles, or flat candles
timeframe_neutral0.1015m 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.
The engine writes three possible outputs:
SignalFileMeaning
YESruntime/decisions.jsonBuy the YES outcome token
NOruntime/decisions.jsonBuy the NO outcome token
HOLDruntime/decisions.json + runtime/manual_review.jsonNot executable; reasons recorded
Every decision carries a 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.

Build docs developers (and LLMs) love