The Problem
Polymarket traders need a repeatable way to capture market‑making strategies, replay them against historic order‑book data, and evaluate profitability. Existing tooling is fragmented, manual, and ties together a mix of on‑chain ingestion, low‑latency execution, and post‑trade analytics. The result is high engineering overhead and unreliable back‑testing.
What This Does
polybot supplies a self‑contained portfolio of seven micro‑services that together provide the full data‑to‑execution pipeline:
- polybot‑core – shared domain models, authentication (
polybot-core/src/main/java/com/polybot/hft/polymarket/auth/PolymarketAuthContext.java) and market discovery utilities. - ingestor‑service – consumes Polymarket trade streams, writes normalized rows into ClickHouse (
ingestor-service/src/main/java/com/polybot/hft/ingestor/ClickHouseWriter.java). - executor‑service – runs live or paper orders, monitors order status (
executor-service/src/main/java/com/polybot/hft/executor/order/ExecutorOrderMonitor.java). - strategy‑service – loads strategy implementations (e.g.,
strategy-service/src/main/java/com/polybot/hft/polymarket/strategy/GabagoolDirectionalEngine.java) and exposes runtime status via REST. - analytics‑service – queries ClickHouse for position‑level metrics, exposing them through
AnalyticsController. - infrastructure‑orchestrator‑service – starts/stops the auxiliary stacks (ClickHouse, Redpanda, Prometheus) and reports health.
- research – Python notebooks and scripts (
research/deep_analysis.py,research/paper_trading_dashboard.py) for offline back‑testing and metric generation.
All services are Maven‑built Java 21 Spring Boot apps, containerised via the Docker Compose files (docker-compose.analytics.yaml, docker-compose.monitoring.yaml). The ClickHouse schema lives under analytics-service/clickhouse/init/.
How It Is Wired
Entry points – each service launches from its *Application.java class (e.g., AnalyticsServiceApplication, ExecutorServiceApplication). Spring Boot creates the REST layer, injects beans from polybot-core, and starts the embedded Tomcat server.
Request flow (analytics example)
- HTTP GET
/api/analytics/status→AnalyticsController(analytics-service/src/main/java/com/polybot/analytics/web/AnalyticsController.java). - Controller calls
UserPositionAnalyticsRepository→ concreteJdbcUserPositionAnalyticsRepository. - Repository obtains a JDBC connection (configured in
application.yaml) and runs ClickHouse SQL defined in theclickhouse/initscripts. - Result set is mapped to POJOs and returned to the client.
Execution flow (executor example)
- Order request arrives at
ExecutorOrderMonitor. - Monitor validates via
PolymarketAuthContext(shared core). - Calls
ExecutorMetricsServicefor latency tracking, then dispatches toExecutorMarketOrderEventorExecutorLimitOrderEvent. - For paper mode,
PaperExchangeSimulator(large file) simulates fills; for live mode it invokesPolymarketBankrollServicewhich signs and sends transactions using the private key from.env.example.
Cross‑service coupling – the only shared artifact is polybot-core. No import cycles were detected; internal modules are isolated, keeping blast radius low. The most widely used core classes are the auth context and market discovery service, each referenced by executor, strategy, and ingestor.
How To Use It
# Clone the exact upstream repo
git clone https://github.com/moses-y/polybot.git
cd polybot
# Install Java 21, Maven 3.8+, Docker Compose
cp .env.example .env
set -a && source .env && set +a # export needed vars
# Build all services (skip tests for speed)
./start-all-services.sh # builds Docker images, starts ClickHouse, Redpanda, Prometheus, Grafana
The script runs mvn clean package -DskipTests for each module and then docker compose -f docker-compose.analytics.yaml up -d plus the monitoring stack. Health can be verified with the curl commands listed in the README (e.g., curl http://localhost:8080/actuator/health).
To run a single service locally:
cd executor-service
mvn spring-boot:run -Dspring-boot.run.profiles=develop
Environment variables required for live trading are documented in .env.example (POLYMARKET_PRIVATE_KEY, POLYMARKET_API_KEY, etc.). The research scripts can be executed directly with Python 3.11 (python research/deep_analysis.py).
Real‑World Use
A quant team can point the ingestor at Polymarket’s public Kafka feed, let strategy-service load a custom Gabagool market‑making engine, and use analytics-service dashboards to compare live P&L against the back‑tested results produced by research/paper_trading_dashboard.py. The modular services allow swapping the strategy implementation without redeploying the whole stack.
Code Health & Issues
- High – CI missing – No GitHub Actions or other pipeline; 169 source files are never built automatically.
- Medium – Dependabot absent – Only Maven
pom.xmlmanifests exist; no bot to keep dependencies patched. - Medium – Test coverage low – 8 test files vs. 169 source files (≈ 5 % coverage).
Static analysis also flagged deep nesting (max depth 9 in several strategy classes), duplicated repository logic, oversized files (> 600 LOC), and broad exception handling, all of which increase maintenance cost.
The Bottom Line
polybot delivers a complete, containerised Polymarket research and execution platform with clear service boundaries and a reusable Java core. It is production‑ready in architecture but needs CI, dependency automation, and broader test coverage before large‑scale deployment. Teams comfortable with Spring Boot, Maven, and ClickHouse will find it a solid foundation for strategy reverse‑engineering.