The Problem
Researchers and analysts need a raw, continuously‑updated record of Polymarket trades, but the blockchain data is large, fragmented, and requires custom cleaning (e.g., unifying token perspectives, filling missing token IDs). Pulling, normalising, and storing this volume manually is error‑prone and time‑consuming.
What This Does
The repository ships a 107 GB, 1.1 billion‑record dataset and a Python toolkit that can fetch on‑chain OrderFilled events, process them into several Parquet tables, and maintain a live sync mode. Core logic lives in polymarket/fetchers/ (RPC calls to Polygon and Gamma API) and polymarket/processors/ (cleaning, token mapping, trade extraction). The CLI in polymarket/cli/main.py exposes commands such as fetch_onchain, process_historical, and update_markets.
How It Is Wired
Execution starts at the console entry point python -m polymarket.cli which runs polymarket/cli/__main__.py → polymarket/cli/main.py. The most used command is cmd_fetch_onchain (line 137) which:
- Calls
get_latest_block→polymarket/fetchers/rpc.py:get_latest_block(uses RPC endpoint frompolymarket/config.py:get_rpc_url). - Retrieves logs via
rpc.get_logsand timestamps viabatch_get_timestamps. - Writes raw logs with
write_batch(defined inpolymarket/tools/continuous_fetch.py).
After fetching, cmd_process_historical (line 703) orchestrates the processing pipeline:
extract_trades(inpolymarket/processors/trades.py) parses raw logs, callingload_token_mapping(used 5 times across the repo) and_parse_order_filled.- Cleaners
clean_tradesandclean_users(inpolymarket/processors/cleaner.py) are invoked, each routing through shared helpers like_process_trades_batch. - Results are written with
write_batchagain and progress saved viasave_progress.
The most connected modules are polymarket/config (imported by 6 others) and polymarket/fetchers/rpc (imported by 4). Functions with the widest blast radius include extract_trades (6 callers) and load_token_mapping (5 callers). No circular imports are present, so changes in a hub module affect many downstream files but do not create feedback loops.
File‑by‑file responsibility (high‑level):
| File | Core Role |
|---|---|
polymarket/cli/main.py | CLI parsing, command dispatch, logging setup |
polymarket/fetchers/rpc.py | Low‑level Polygon RPC calls |
polymarket/fetchers/gamma.py | Gamma API market list retrieval |
polymarket/processors/trades.py | Trade extraction, token mapping, preview CSV |
polymarket/processors/cleaner.py | Data‑frame sanitisation for users & trades |
polymarket/tools/continuous_fetch.py | Batch writer, CSV preview, graceful shutdown |
polymarket/tools/sort_parquet.py | External sort of large Parquet files |
polymarket/tools/merge_*.py | Schema conversion & file merging utilities |
How To Use It
# Clone the repo
git clone https://github.com/moses-y/Polymarket_data.git
cd Polymarket_data
# Install Python dependencies
pip install -r requirements.txt
# Optional: set RPC endpoint (default in config falls back to env var POLYMARKET_RPC_URL)
export POLYMARKET_RPC_URL="https://polygon-rpc.com"
# Fetch the latest on‑chain logs (writes to data/ folder)
python -m polymarket.cli fetch_onchain
# Process fetched logs into analysis‑ready Parquet tables
python -m polymarket.cli process_historical --start-block 0 --end-block latest
# For continuous sync (runs until stopped)
python -m polymarket.tools.continuous_fetch
The README lists equivalent shell wrappers in scripts/ (e.g., scripts/fetch_onchain.sh), but the Python commands above are the canonical entry points.
Real‑World Use
A quant team could schedule python -m polymarket.cli fetch_onchain every 2 seconds via a cron job, then run process_historical nightly to update trades.parquet and users.parquet. Downstream notebooks would load the Parquet files directly with pandas.read_parquet for factor‑model construction or behavioural clustering.
Code Health & Issues
- High – Cognitive Load – Deep nesting (max depth 8) in
fetchers/rpc.py,cli/main.py,processors/cleaner.py. Refactor with early returns or helper functions. - High – Clarity – Repeated 6‑line blocks across four
tools/*scripts. Extract shared helpers to reduce duplication. - Medium – Resilience – Broad
except:clauses infetchers/rpc.py,cli/main.py,tools/continuous_fetch.py. Replace with specific exception handling. - Medium – Cognitive Load –
cli/main.pyis 958 lines; split into sub‑modules (e.g.,commands_fetch.py,commands_process.py). - Medium – SDLC – No test suite present. Adding unit tests for fetchers and processors would catch regressions.
- Medium – CI/CD – No CI configuration; integrating GitHub Actions for linting and testing is advisable.
- Low – Dependency Management – Only
requirements.txt, no lockfile; builds may be non‑reproducible across environments.
The Bottom Line
The repo delivers a ready‑to‑use, large‑scale Polymarket dataset and a functional fetch‑process pipeline, but the codebase is tightly coupled, deeply nested, and lacks automated testing or CI. It is suitable for data‑science teams comfortable with Python and willing to invest in refactoring for maintainability.