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 runtime/ directory is the sole inter-stage communication channel for the PolyClaw Trading pipeline. Every stage — fetch, candles, analyze, signal, bankroll, validate, execute, and report — reads its inputs and writes its outputs exclusively as versioned JSON files under this directory. Nothing in runtime/ is a source file, a configuration file, or a secret store: it is generated state only, created fresh on every pipeline run.
runtime/ must never contain secrets of any kind. API keys, private keys, proxy credentials, wallet addresses, and RPC URLs belong exclusively in .env.local or environment variables. Any secret that appears in a runtime file is considered a security incident. The tests/test_secret_scanner.py test fails the build if secret-like patterns are detected anywhere in the workspace.

JSON envelope

Every required runtime file uses a common versioned envelope so that any stage can verify it is reading output produced by the expected upstream stage at a known schema version.
{
  "schema_version": 1,
  "stage": "signal",
  "generated_at": "2026-01-01T12:00:00Z",
  "data": {}
}
FieldTypeDescription
schema_versionintegerAlways 1 for the current engine. Mismatches fail closed.
stagestringName of the stage that wrote the file (e.g. "signal").
generated_atstringISO 8601 UTC timestamp of when the file was written.
dataobjectStage-specific payload; structure is documented per file below.

Atomic writes

All writes follow a strict atomic sequence to prevent a downstream stage from reading a partially written file:
  1. A unique temporary sibling file is created next to the target path.
  2. The JSON payload is written and fsync-ed to the temporary file.
  3. os.replace atomically moves the temporary file to the final path.
This means a file either contains a complete, valid payload or it does not exist at all from the perspective of any reader.

Freshness checks

Several stages enforce a maximum age on their input files before proceeding. If a file’s generated_at timestamp is older than the configured limit, the stage fails closed rather than acting on stale state. The freshness limits are controlled by environment variables and are documented in the table below alongside each file. Invalid JSON, duplicate keys, wrong schema_version, wrong stage, missing required fields, stale timestamps, non-finite numbers, bad price bounds, bad OHLC geometry, unsupported timeframes, and non-monotonic timestamps all cause the consuming stage to fail closed.

Runtime file inventory

FileWritten by stageFreshness limitDescription
runtime/market_snapshot.jsonfetchMAX_MARKET_AGE_SEC (600 s)Active BTC markets discovered from the Polymarket Gamma keyset API
runtime/candles.jsoncandlesMAX_CANDLE_AGE_SEC (1200 s)UTC-aligned 5 m and 15 m pseudo-OHLC candle objects per market
runtime/market_analysis.jsonanalyzeQuality score, EMA8/EMA21, RSI14, ATR14, POC, realized volatility
runtime/decisions.jsonsignalMAX_DECISION_AGE_SEC (600 s)YES / NO / HOLD decision with confidence score
runtime/bankroll_state.jsonbankrollMAX_BANKROLL_AGE_SEC (600 s)Equity, free balance, drawdown %, reserve, open exposure
runtime/risk_state.jsonvalidateSized, validated decision ready for the execute stage
runtime/trade_registry.jsonexecuteActive positions, pending orders, execution ledger, and failed attempts
runtime/execution_status.jsonexecuteCurrent execution mode, last result, and attempt/block lists
runtime/manual_review.jsonsignal / validateHOLD record with human-readable reason when no executable decision is produced
runtime/runtime_snapshot.jsonreportFull pipeline snapshot written at the end of each cycle
runtime/executions/YYYYMMDD.jsonexecuteDaily execution ledger; one file per UTC calendar day
runtime/copy_wallet_signals.jsoncopy_tradingCopy-trade signals sourced from tracked public wallets
runtime/wallet_watchlist.jsontrader_trackerScored wallet watchlist from the Polymarket trader tracker
runtime/spot_prices.jsonmarket_data_sourcesCoinGecko spot prices for configured asset IDs
runtime/macos-runner.logpolyclaw-macPipeline output written by the native macOS Swift runner

File details

runtime/market_snapshot.json

Written by the fetch stage after paginating the Polymarket Gamma keyset API. Contains the normalized set of active binary BTC/Bitcoin markets that passed question-semantic validation. The freshness limit is MAX_MARKET_AGE_SEC (default 600 seconds); the candles stage refuses to proceed if this file is older than that limit.
{
  "schema_version": 1,
  "stage": "fetch",
  "generated_at": "2026-01-01T12:00:00Z",
  "data": {
    "markets": [
      {
        "market_id": "...",
        "question": "Will BTC exceed $100,000 by end of day?",
        "end_date": "2026-01-01T23:59:00Z",
        "active": true,
        "closed": false,
        "resolved": false,
        "accepting_orders": true,
        "yes_token_id": "...",
        "no_token_id": "...",
        "yes_price": 0.54,
        "no_price": 0.46,
        "liquidity_usd": 2500.0,
        "volume_24h_usd": 8000.0,
        "semantic_mapping": {
          "bullish_side": "YES",
          "bearish_side": "NO",
          "mapping_confidence": 0.97,
          "mapping_reason": "Bullish BTC outcome maps directly to YES"
        },
        "price_history": [
          {"t": 1735730400, "p": 0.52},
          {"t": 1735730460, "p": 0.54}
        ]
      }
    ]
  }
}

runtime/candles.json

Written by the candles stage. Contains UTC-aligned pseudo-OHLC candle objects for each selected market at both the 5 m (execution) and 15 m (confirmation) timeframes. History is fetched from the Polymarket CLOB YES-token prices endpoint using standard-library urllib only.
{
  "schema_version": 1,
  "stage": "candles",
  "generated_at": "2026-01-01T12:00:00Z",
  "data": {
    "markets": [
      {
        "market_id": "...",
        "question": "Will BTC exceed $100,000 by end of day?",
        "semantic_mapping": {
          "bullish_side": "YES",
          "bearish_side": "NO",
          "mapping_confidence": 0.97,
          "mapping_reason": "Bullish BTC outcome maps directly to YES"
        },
        "samples": [
          {"t": 1735730400, "p": 0.52}
        ],
        "timeframes": {
          "5m": {
            "candles": [
              {
                "timestamp": "2026-01-01T11:00:00Z",
                "open": 0.50,
                "high": 0.55,
                "low": 0.48,
                "close": 0.53,
                "sample_count": 4,
                "complete": true
              }
            ]
          },
          "15m": {
            "candles": []
          }
        }
      }
    ]
  }
}

runtime/market_analysis.json

Written by the analyze stage. Contains the full indicator and quality payload for each market. There is no enforced freshness limit on this file; the signal stage reads it directly after analyze completes within the same pipeline cycle. The data object includes per-market entries containing:
  • Quality score — a 0–1 composite reflecting candle completeness, sample density, flat-candle ratio, and missing-bucket ratio.
  • EMA8 / EMA21 — exponential moving averages seeded from the first observation, alpha = 2 / (period + 1).
  • RSI14 — Wilder-smoothed RSI after an arithmetic-mean seed over the first 14 deltas.
  • ATR14 — Wilder-smoothed average true range; TR = max(high−low, |high−prev_close|, |low−prev_close|).
  • POC — the nearest POC_BIN_SIZE price bin holding the greatest public observation count. This is sample-density context, not traded-volume POC.
  • Realized volatility — population standard deviation of the latest 20 simple close-to-close returns.
  • Pattern evidence — results of all nine deterministic pattern groups (engulfing, harami, tweezers, morning/evening star, three soldiers/crows, shadow breakout, order-block sweep, impulse, POC context).

runtime/decisions.json

Written by the signal stage. Contains the YES / NO / HOLD decision for each analyzed market along with a deterministic confidence score. The freshness limit is MAX_DECISION_AGE_SEC (default 600 seconds).
{
  "schema_version": 1,
  "stage": "signal",
  "generated_at": "2026-01-01T12:00:00Z",
  "data": {
    "decisions": [
      {
        "decision_id": "...",
        "market_id": "...",
        "question": "Will BTC exceed $100,000 by end of day?",
        "signal": "YES",
        "side": "YES",
        "confidence": 0.78,
        "reason": "Bullish EMA crossover confirmed by 15m; morning star pattern.",
        "semantic_mapping": {
          "bullish_side": "YES",
          "bearish_side": "NO",
          "mapping_confidence": 0.97,
          "mapping_reason": "Bullish BTC outcome maps directly to YES"
        },
        "risk_validation": {
          "approved": true,
          "blocking_reasons": []
        }
      }
    ]
  }
}
A confidence below MIN_EXECUTION_CONFIDENCE (default 0.72), a lone harami, mixed high-strength patterns, EMA/RSI conflict, 5 m / 15 m timeframe conflict, uncertain market wording, low candle quality, or overextension all produce HOLD and write a manual_review.json record instead of an executable decision.

runtime/bankroll_state.json

Written by the bankroll stage. Contains the current equity snapshot, free balance available for new positions, drawdown percentage, locked reserve, and open exposure. The freshness limit is MAX_BANKROLL_AGE_SEC (default 600 seconds). The validate stage requires a fresh bankroll state before sizing any decision.
{
  "schema_version": 1,
  "stage": "bankroll",
  "generated_at": "2026-01-01T12:00:00Z",
  "data": {
    "day_key": "20260101",
    "equity_usd": 98.50,
    "working_bankroll_usd": 88.65,
    "reserve_usd": 10.00,
    "free_balance_usd": 72.30,
    "open_exposure_usd": 16.20,
    "drawdown_pct": 1.50,
    "risk_mode": "normal",
    "risk_multiplier": 1.0
  }
}

runtime/risk_state.json

Written by the validate stage after applying every active capital cap. Contains the fully sized and validated risk limits and remaining capacity that is safe to hand to the execute stage. There is no additional freshness limit; it is consumed immediately by execute within the same cycle. The validate stage repeats all semantic, quality, expiry, cooldown, duplicate, and risk checks before writing this file. A decision that passes signal but fails any of these re-checks at validation time produces a HOLD and updates manual_review.json.

runtime/trade_registry.json

Written by the execute stage. Contains the current active positions, pending orders, completed executions, and failed attempts. Used by the bankroll stage to compute realized P&L, drawdown, daily trade counts, and open exposure.

runtime/execution_status.json

Written by the execute stage. Records the current execution mode (dry-run or live), the live_enabled flag, the last result string, and lists of recent attempts and blocked orders.

runtime/executions/YYYYMMDD.json

Written by the execute stage. One file per UTC calendar day (e.g. runtime/executions/20260101.json). Contains every execution ledger entry for that day, including both dry-run and live-mode entries so operator behavior is auditable before going live.
[
  {
    "ts": "2026-01-01T12:05:00Z",
    "market_id": "...",
    "side": "YES",
    "size_usd": 0.75,
    "confidence": 0.78,
    "mode": "dry-run",
    "rc": 0
  }
]

runtime/manual_review.json

Written by the signal or validate stage whenever no executable decision is produced. Contains a human-readable reason explaining why the pipeline produced a HOLD — for example, low confidence, candle quality below threshold, EMA/RSI conflict, or uncertain market semantics. Operators should review this file when the pipeline consistently produces HOLDs to understand what conditions are not being met.

runtime/runtime_snapshot.json

Written by the report stage at the end of each pipeline cycle. Contains a full snapshot of the pipeline state, combining key fields from all other runtime contracts into a single artifact for dashboard consumption and audit review.

runtime/copy_wallet_signals.json

Written by the copy_trading module. Contains copy-trade signals synthesized from the scoring of tracked public Polymarket wallets. The trader_tracker.py and wallet_scoring.py modules supply the underlying wallet data. Signals here are advisory and do not feed the deterministic execution gate.

runtime/wallet_watchlist.json

Written by the trader_tracker module. Contains a scored list of public Polymarket wallets that meet the minimum trade count and other criteria configured via TRADER_TRACKER_* variables.

runtime/spot_prices.json

Written by market_data_sources.py using the public CoinGecko API (no API key required). Contains spot prices for the asset IDs listed in COINGECKO_IDS (default: bitcoin,ethereum,solana).

runtime/macos-runner.log

Written by the native macOS Swift runner (polyclaw-mac). Contains the pipeline’s stdout/stderr output from the Swift process layer. The Swift runner discovers the checkout from the current directory (or OPENCLAW_WORKSPACE), loads .env.local without echoing values, and routes all pipeline output to this file.
The runtime/macos-runner.log file is the only non-JSON artifact in runtime/. It is treated as an append-only log; the Swift runner does not rotate it automatically. Operators should monitor its size in long-running deployments.

Build docs developers (and LLMs) love