Service-oriented pnpm monorepo that discovers Polymarket YES/NO markets, hydrates order books from official APIs, ranks executable arbitrage opportunities by expected real profitability, stores them in PostgreSQL, exposes them through a Fastify API, and renders a React + Tailwind dashboard with alert history and system health.
- Node.js 24 target runtime
- pnpm workspace monorepo
- TypeScript across apps, packages, and services
- PostgreSQL + Prisma ORM
- React + Tailwind CSS
- Docker Compose for local infrastructure
- Email alerting via SMTP or Resend
apps/
api
web
packages/
config
db
email
logger
polymarket-client
types
utils
services/
alert-service
arb-engine-service
book-service
health-service
persistence-service
scanner-service
score-service
- Official Polymarket Gamma discovery for active markets
- Official CLOB order book and fee-rate ingestion
- WebSocket market-channel support with reconnect handling and incremental book updates
- Executable-depth arbitrage simulation for
50,100,250,500USDC budgets - Safety buffers, stale-data rejection, tick-size/min-order-size gating
- Multi-level executable-depth simulation with dynamic slippage and latency degradation estimates
- Profitability-first scoring with:
- expected net profit in USD
- execution confidence
- persistence confidence
- liquidity quality
- market quality
- historical conversion score
- profitability rank and risk-adjusted profitability rank
- Email alert rules based on grade plus profitability thresholds, cooldown, and confidence gates
- Historical analytics buckets that learn from observed signal durability and decay
- Algorithm diagnostics with:
- full scan funnel counts from scanned markets to alert-qualified candidates
- normalized rejection reasons and near-miss samples
- threshold sensitivity distributions
- production vs relaxed vs research shadow profiles
- persisted diagnostics snapshots for historical calibration
- Persistent signal episodes with:
- initial profitable snapshot
- throttled observations over time
- lifecycle close reason and decay milestones at
500ms,1s,3s,5s, and10s
- Live dashboard defaults to fresh, active
A/Bopportunities only, with paginated results and filtered KPI aggregates - Detail view exposes profitability diagnostics, latency-adjusted edge, and risk metrics
- Historical analysis section with filters, pagination, lifecycle metrics, and per-signal detail
- PostgreSQL persistence for markets, books, opportunities, observations, alerts, health, and future execution tables
- Fastify API endpoints:
/api/opportunities/api/opportunities/:id/api/history/api/history/metrics/api/history/:id/api/history/:id/observations/api/themes/api/grades/api/alerts/api/health/api/config/public/api/diagnostics/funnel/api/diagnostics/rejections/api/diagnostics/profiles/api/diagnostics/themes/api/diagnostics/history/api/diagnostics/distributions/api/diagnostics/config
- React dashboard pages:
- Live opportunities
- Opportunity detail
- Historical signals
- Historical signal detail
- Alerts history
- System health
- Algorithm diagnostics
- Copy
.env.exampleto.envand adjust values. - Install dependencies:
pnpm install- Start PostgreSQL, Redis, and MailHog:
docker compose -f docker-compose.dev.yml up postgres redis mailhog -d- Initialize the database schema:
pnpm db:generate
pnpm db:init- Optionally seed demo data:
pnpm db:seed- Start the API, scanner, and web app:
pnpm devStart the full stack:
cp .env.example .env
docker compose -f docker-compose.dev.yml up --buildMailHog UI is available at http://localhost:8025.
The Docker stack now runs a one-shot db-init service before api and scanner, so Prisma migrations are applied automatically when the containers start.
You can tune the bootstrap behavior with DB_INIT_MAX_ATTEMPTS, DB_INIT_RETRY_DELAY_MS, and DB_SEED_ON_INIT.
Live opportunity quality can be tuned with:
MIN_DISPLAY_NET_EDGE_BPSMIN_REAL_EDGE_BPSMIN_PERSISTED_NET_EDGE_BPSOBSERVATION_MIN_INTERVAL_MSOBSERVATION_MIN_EDGE_DELTA_BPSOBSERVATION_MIN_SCORE_DELTAMIN_ALERT_NET_EDGE_BPSMIN_ALERT_EXPECTED_PROFIT_USDMIN_ALERT_EXECUTION_CONFIDENCEMIN_ALERT_PERSISTENCE_CONFIDENCEMIN_ALERT_MARKET_QUALITYANALYTICS_REFRESH_INTERVAL_MSANALYTICS_LOOKBACK_HOURSDEFAULT_PAGE_SIZEMAX_PAGE_SIZE
Diagnostics and calibration can be tuned with:
ENABLE_DIAGNOSTICSENABLE_RELAXED_SHADOW_EVALUATIONENABLE_RESEARCH_SHADOW_EVALUATIONDIAGNOSTICS_PERSIST_INTERVAL_MSDIAGNOSTICS_SAMPLE_LIMIT
The diagnostics dashboard exposes the active runtime thresholds, funnel drop-off, rejection reasons, theme breakdowns, distribution buckets, shadow-profile deltas, and historical diagnostics snapshots so you can answer whether the market is quiet or the production profile is filtering too aggressively.
pnpm devpnpm buildpnpm typecheckpnpm lintpnpm testpnpm db:generatepnpm db:initpnpm db:migratepnpm db:seedpnpm analytics:reportpnpm docker:dev
- The repo targets Node.js 24. If your host machine still runs Node 20, use Docker or upgrade the local runtime before relying on local execution.
- The scanner currently focuses on executable binary YES/NO arbitrage. Negative-risk and execution-intent tables are already present to support the next phase.
- Historical signal learning is observational only. It records opportunity outcomes and aggregates conversion buckets, but it does not place trades.
- The UI is seeded with demo data after
pnpm db:seed, so the dashboard is usable before live Polymarket sync completes.