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.

Docker is the fastest way to run PolyClaw Trading without touching your local Python installation. The included Dockerfile and docker-compose.yml give you a reproducible, isolated environment that preserves every dry-run ledger and execution record in a bind-mounted ./runtime directory. The safety default (LIVE_TRADING=0) is unchanged inside Docker — the container never places a real order unless you explicitly opt in.

Prerequisites

  • Docker and Docker Compose installed and running
  • A copy of the repository cloned locally
  • Your API keys and wallet address ready for .env.local

How It Works

Dockerfile

The image is built from python:3.12-slim and keeps the environment lean and deterministic:
FROM python:3.12-slim

WORKDIR /app

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

COPY . /app

RUN pip install --no-cache-dir .

# Runtime and logs are expected on a mounted volume/bind at /app/runtime.
RUN mkdir -p /app/runtime

ENTRYPOINT ["python", "run_pipeline.py"]
CMD ["dry-run"]
The entrypoint is run_pipeline.py and the default command is dry-run, so the container will never accidentally go live without an explicit override.

docker-compose.yml

The Compose file wires the build context, env file, command, and volume mount together:
services:
  openclaw:
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - .env.local
    command: ["dry-run"]
    volumes:
      - ./runtime:/app/runtime
    restart: unless-stopped
The ./runtime directory on your host is bind-mounted to /app/runtime inside the container, so all candle data, decisions, bankroll state, trade history, and execution ledgers persist across container restarts.

Quickstart

1

Copy and configure the environment file

Copy the example env file and fill in the values you need. LIVE_TRADING defaults to 0 — leave it that way until you have validated behavior in dry-run mode.
cp .env.example .env.local
Open .env.local in your editor and set at minimum:
POLYMARKET_WALLET_ADDRESS=0x...
CHAINSTACK_NODE=https://...
OPENROUTER_API_KEY=sk-...
2

Build the image and start the pipeline

docker compose up --build
Compose builds the image, reads .env.local, and starts the dry-run pipeline. Runtime artifacts accumulate in ./runtime on your host.
3

Verify the run

While the container is running, you can inspect runtime state directly on the host:
cat runtime/decisions.json
cat runtime/bankroll_state.json
Or follow the container’s live output:
docker compose logs -f

State Persistence

The runtime/ directory is bind-mounted from host to container (./runtime:/app/runtime). Everything written by the pipeline — candle snapshots, trade decisions, the bankroll ledger, daily execution records — survives container restarts. The layout is:
PathContents
runtime/decisions.jsonLatest trade decisions
runtime/bankroll_state.jsonEquity and risk limits
runtime/trade_history.jsonFull trade history
runtime/open_positions_snapshot.jsonCurrent open positions
runtime/manual_review.jsonFallback when no usable candle feed
runtime/executions/YYYYMMDD.jsonDaily execution ledger

Dashboard

The Mission Control dashboard is a Flask app (bot/dashboard/) that binds to loopback by default. To expose it outside the container, add a ports entry to docker-compose.yml and set DASHBOARD_PORT in .env.local (default 8080). Always set DASHBOARD_AUTH_TOKEN before exposing the dashboard outside localhost:
DASHBOARD_PORT=8080
DASHBOARD_AUTH_TOKEN=your-secret-token-here

Environment Variables

All configuration is injected from .env.local via the env_file directive in docker-compose.yml. Key safety variables:
VariableDefaultPurpose
LIVE_TRADING0Hard gate: 0 logs orders, 1 sends them via PolyClaw
ALLOW_REDEEM0Automatic redeem on resolved markets (opt-in)
MIN_TRADE_USD / MAX_TRADE_USD0.25 / 1.00Micro-order size bounds
BASE_RISK_PER_TRADE_PCT / MAX_DAILY_RISK_PCT1 / 8Per-trade and daily risk caps
MAX_OPEN_EXPOSURE_PCT20Working-bankroll exposure cap
MAX_TRADES_PER_DAY6Daily execution cap
DASHBOARD_PORT8080Port the dashboard listens on
DASHBOARD_AUTH_TOKEN(unset)Token required for dashboard access when set

Enabling Live Mode

Docker does not change the safety model. Live mode requires the same explicit opt-in as any other deployment method: set LIVE_TRADING=1 in .env.local and complete the manual wallet approval step.
Live mode sends real orders through PolyClaw. Only enable LIVE_TRADING=1 after validating your configuration through multiple dry-run cycles. Fund your wallet with only what you are prepared to lose.
# In .env.local
LIVE_TRADING=1
ALLOW_REDEEM=0    # set to 1 only if you want automatic redeems
Then update docker-compose.yml to pass the live command:
command: ["live", "--confirm-live"]

Stopping

docker compose down
State remains intact in ./runtime and will be picked up automatically on the next docker compose up.

Build docs developers (and LLMs) love