Arbitrax

Drag-and-drop trading bots for Polymarket. KeeperHub under the hood, paper trades by default.

Arbitrax

Created At

Open Agents

Project Description

Arbitrax is the simplest place to build, backtest, and run automated trading bots on Polymarket — without writing code, managing wallets, or knowing what a CLOB token ID is.

Lots of people want to run automated bots on Polymarket 24/7, but there's no easy place to actually build one. You either write your own webhook plumbing, key management, order routing, paper-trade harnesses, and monitoring — or you don't trade automatically. Existing TradingView traders who already have working strategies hit the same wall: their alerts have nowhere to fire.

Arbitrax fixes that for two audiences. TradingView traders drop the bot's webhook URL into their existing alerts and get a 24/7 Polymarket bot with zero migration. Non-coders drag and drop a strategy on a canvas — pick a trigger, evaluate a signal with a Pine-style script over live Bitstamp candles, place an order — and the bot is running in two minutes.

The killer detail: users never pick a market. Polymarket runs auto-rotating up/down markets every 15m / 1h / 4h / 1d window. Users pick asset + timeframe, and on every fire the bot computes the live slug, resolves token IDs, and trades. The editor shows a live preview of what market the bot will hit right now.

Paper trading is on by default — every fill is simulated at the live market price and recorded as a trade, so you get realistic P&L without risking USDC. Same axes as our backtest engine, so a strategy that works in backtest works in production. Flip paper off when you're ready to trade real USDC on Polygon.

Arbitrax is the surface. KeeperHub is the engine. Every bot you build is a real KeeperHub workflow under the hood — KH stores it, schedules it, retries it, executes it. We didn't replicate KH's runtime; we use it.

How it's Made

Architecture. Arbitrax is a Next.js 16 frontend + NestJS 11 backend, with KeeperHub as the workflow execution engine sitting underneath. Single rule: every bot in Arbitrax is a KeeperHub workflow. Nothing else. The Bot row in our Postgres is intentionally a pure pointer — { id, userId, name, status, keeperhubWorkflowId }. All bot logic lives in the KH workflow.

The editor is the centerpiece. We built our own drag-and-drop canvas inside Arbitrax (using @xyflow/react — same library KeeperHub uses internally — plus dagre for auto-layout and jotai for state) so users never leave our app. The canvas emits the exact { nodes, edges } JSON KeeperHub expects and writes it via PATCH /api/workflows/{id}. You can verify the integration is real with one curl: curl http://localhost:3100/api/workflows/{id} | jq .nodes returns the same JSON the editor just produced. Auto-bridge on delete (predecessors automatically reconnect to successors), ⌘S to save, Test run button to fire the trigger once.

The KeeperHub plugin we wrote (zlabs-polymarket) ships 6 actions: search-markets, get-odds, pine-evaluate, voting-aggregate, strategy-run, place-order. It registers as a normal KH integration through the standard plugin discovery system (pnpm discover-plugins). The plugin is open-source and submittable on its own — the KH team explicitly weighs standalone plugins higher than closed dependencies inside a third-party app.

Real-time data, no API keys. Pine Evaluate fetches live OHLC candles from the public Bitstamp API (btcusd / ethusd, 15m/1h/4h/1d) — no key needed. Get Odds and Place Order resolve the live slug from (asset, timeframe), hit gamma-api.polymarket.com/markets?slug=… for CLOB token IDs, then clob.polymarket.com/prices for live UP/DOWN odds in a single batch POST.

Paper mode by default. Every place-order step computes a synthetic fill at the current live market price and records it as a Trade row keyed by keeperhubExecutionId (idempotent upsert). Live mode (gated behind a wallet) signs market FOK orders via py-clob-client. The mirror flow runs from KH back to Arbitrax via POST /v1/ingest/trade with bearer auth (ZLABS_INGEST_SECRET).

Backtest engine matches uploaded TradingView CSVs against actual Polymarket up/down markets that were live in each signal's window — same (asset, timeframe) axes as the live bot, so backtest results translate directly to production behavior.

Stack: Next.js 16 (Turbopack), React 19, Auth.js v5, Jotai, @xyflow/react, dagre, Tailwind, Lucide; NestJS 11, Prisma 7, PostgreSQL 16, Stripe; KeeperHub self-hosted; Polymarket Gamma + CLOB; Bitstamp public OHLC.

Notably hacky: the live active-market preview pill in the config panel re-renders every 30 seconds with the slug the bot will currently hit (btc-updown-15m-${flooredStartTs}), so users always see exactly what's being targeted. It's a tiny detail that makes the auto-active-market model click visually — judges will see "BTC + 15m" → live slug → window → Bitstamp pair, all at once, and instantly understand why users never have to pick a market manually.

background image mobile

Join the mailing list

Get the latest news and updates

Arbitrax | ETHGlobal