top of page
Search

How to Build a Polymarket Arbitrage Bot With Claude Fable 5

  • Writer: Sandra Wakefield
    Sandra Wakefield
  • 22 hours ago
  • 24 min read

A production-minded framework for discovering mispriced outcome baskets, executing hedged orders, controlling leg risk, and deploying without donating your capital to latency


By Sally Fong and Joseph Plazo


Appendix:



Most people imagine an arbitrage bot as a small mechanical genius: it spots two prices that do not add up, clicks twice, and quietly manufactures money while its owner sleeps.


The reality is less Disney and more submarine warfare.


The arithmetic is easy. The danger lives between the arithmetic and the fills.

A YES token costs $0.47. A NO token costs $0.51. Together they cost $0.98 and can be merged into $1. You appear to have found two cents lying unattended on the pavement.


Then the YES order fills, the NO price moves to $0.55, your second order fails, the WebSocket disconnects, and your “risk-free” trade becomes a directional position in an election you have not followed since breakfast.


Arbitrage is not the discovery of a price discrepancy. It is the successful capture, hedging, settlement, and reconciliation of that discrepancy.


This guide shows you how to build that entire machine.


It uses Claude Fable 5 to accelerate engineering, testing, documentation, and code review. It does not put Claude in the live execution path. Language models are excellent builders. They are inappropriate millisecond-by-millisecond risk managers.


1. The Opportunity

Polymarket operates a central limit order book with off-chain matching and on-chain settlement. Orders are locally signed EIP-712 messages, while matched trades settle on Polygon. Public market data is accessible without authentication; order placement and cancellation require authenticated credentials.


As of July 2026, production integrations should use Polymarket’s CLOB V2 infrastructure. CLOB V2 became the production standard on April 28, 2026, introduced pUSD as collateral, and made older V1-signed production orders obsolete. The official V2 clients are available in TypeScript, Python, and Rust.


That matters because many bot tutorials age like milk in direct sunlight. They may reference:


  • Old client libraries

  • USDC.e instead of pUSD

  • Deprecated authentication formats

  • Polling instead of live order-book updates

  • Simplistic top-of-book calculations

  • No accounting for taker fees

  • No handling of negative-risk events

  • No recovery after one-sided fills

The opportunity exists because prediction markets are fragmented across thousands of outcome books, participant behavior is uneven, and prices can briefly violate relationships that should hold mathematically or logically.


The sophisticated operator understands an important distinction:


A theoretical arbitrage is a pricing observation. An executable arbitrage is a state machine.

Your bot therefore needs five capabilities:

  1. Discover valid relationships between outcome tokens.

  2. Calculate profits using actual executable depth.

  3. Include fees, slippage, latency, and settlement costs.

  4. Execute without allowing uncontrolled leg exposure.

  5. Reconcile every fill, cancellation, merge, and balance change.


2. What “Using Claude Fable” Actually Means

Claude Fable 5 is Anthropic’s current high-capability model for long-horizon reasoning and agentic engineering. Its Claude API model ID is claude-fable-5. Anthropic currently lists Fable pricing at $10 per million base input tokens and $50 per million output tokens, with lower batch pricing.


Claude Code is an agentic development environment that can inspect a repository, edit multiple files, execute commands, and run tests. It can be installed with:


npm install -g @anthropic-ai/claude-code

The current npm distribution requires Node.js 22 or later, although the downloaded native binary handles runtime execution.


Use Fable for:

  • Designing the architecture

  • Generating typed interfaces

  • Implementing market-data adapters

  • Writing unit and integration tests

  • Simulating partial fills

  • Reviewing fee calculations

  • Creating deployment configuration

  • Finding race conditions

  • Maintaining documentation

  • Examining logs after failures


Do not use Fable for:

  • Deciding live order prices on every market update

  • Holding production wallet credentials

  • Autonomously overriding risk limits

  • Interpreting ambiguous market rules and immediately trading

  • Executing shell commands on a production host with unrestricted permissions


Claude Code hooks execute with the permissions of your local user and can access or modify files available to that user. Treat agent permissions as a security perimeter, not a convenience checkbox.


Claude builds the cockpit. Deterministic code flies the aircraft.


3. Who This Project Is For

This framework is a strong fit for someone who:

  • Can read TypeScript or Python

  • Understands asynchronous programming

  • Is comfortable with APIs, WebSockets, and wallet signing

  • Can tolerate weeks of testing before meaningful live deployment

  • Enjoys investigating edge cases

  • Accepts that “risk-free” is marketing language, not an engineering property

  • Can maintain disciplined capital limits


Helpful skills include:

  • Node.js or Python

  • Order-book mechanics

  • Decimal arithmetic

  • Docker

  • PostgreSQL

  • Redis

  • Polygon transaction monitoring

  • Observability and alerting

  • Basic probability and accounting


Minimum resources


For a credible first version:

  • Development time: 40–80 focused hours

  • Shadow-testing time: at least 1–2 weeks

  • Infrastructure: approximately $20–$100 per month

  • Claude usage: approximately $20–$200 during a serious build, depending on context size and iteration volume

  • Initial test capital: $100–$500

  • Initial live capital after validation: commonly $500–$5,000


Those capital ranges are implementation suggestions, not guarantees of profitability.


This is a poor fit when:


  • You need immediate income

  • You plan to copy code without understanding it

  • You want to run from an ineligible jurisdiction

  • You intend to bypass geographic restrictions

  • You cannot monitor the bot during early live operation

  • A 10% drawdown would affect your rent, debt payments, or basic expenses


Polymarket provides a geographic-restriction endpoint and explicitly restricts order placement from certain locations. Check eligibility before enabling live orders and never design the system to evade restrictions.


4. The Strategic Foundation

Principle 1: Trade executable prices, not displayed probabilities

The headline price shown on a market is not necessarily the price at which your desired position size can execute. Your calculation must walk the order book.


Suppose:

  • 10 YES shares are offered at $0.47

  • The next 90 YES shares are offered at $0.52

  • 100 NO shares are offered at $0.51


The apparent top-of-book sum is:

0.47 + 0.51 = 0.98

But the cost of buying 100 pairs is:

YES cost = 10 × 0.47 + 90 × 0.52 = 51.50
NO cost  = 100 × 0.51              = 51.00
Total    = 102.50

That is not an arbitrage. It is a small ceremony in which you pay $102.50 to obtain $100.


Principle 2: Calculate edge after every cost

Your opportunity formula must include:

  • Weighted execution price

  • Taker fees

  • Slippage allowance

  • On-chain merge or conversion costs

  • Failure and hedge allowance

  • Minimum profit buffer

  • Capital lock-up time

Polymarket currently applies taker fees in several categories. Makers are not charged trading fees. The documented taker-fee formula is:

fee = shares × feeRate × price × (1 - price)

Fee parameters vary by market category and should be retrieved for the individual market rather than hard-coded permanently. Geopolitical and world-event markets are currently fee-free, but fee schedules can change.


Principle 3: Never assume multi-leg atomicity

Polymarket supports GTC, GTD, FOK, and FAK orders. FOK means a particular order must fill immediately and completely or cancel; FAK fills available quantity and cancels the remainder.


The documentation defines those guarantees per order. Therefore, design as though two separate orders can produce different outcomes even when submitted almost simultaneously.


Your bot must survive:

  • Leg A fills and Leg B fails

  • Leg A partially fills

  • Both fill at different quantities

  • The response times out although the order was accepted

  • The order fills after your local process loses its connection

  • Your cancellation arrives after a fill

  • The book changes between detection and submission


Principle 4: A stale book is a false reality

The public market WebSocket provides order-book snapshots, price changes, trades, best-bid/ask updates, and tick-size changes. The market channel currently uses:

wss://ws-subscriptions-clob.polymarket.com/ws/market

The bot must listen for both book and tick-size updates. Polymarket can change a market’s tick size when prices approach the extremes.


A strategy should refuse to trade when:

  • The local book is older than its configured threshold

  • A sequence gap is suspected

  • The WebSocket has reconnected but a REST resnapshot has not completed

  • The exchange clock and local clock differ materially

  • One token book is fresh and its paired token book is stale

A price without a timestamp is gossip.

Principle 5: Build a system, not a script

A script detects an opportunity.


A system knows:

  • Whether the opportunity is valid

  • Whether capital is available

  • Whether the market is eligible

  • Whether the books are synchronized

  • Whether an earlier order is unresolved

  • Whether inventory limits permit the trade

  • Whether the bot is already exposed

  • Whether the trade actually settled

  • Whether it should shut itself down


5. The Arbitrage Strategies

Start with one strategy. Add complexity only after the first strategy survives live micro-trading.


Strategy A: Binary complement arbitrage

Every standard binary market has YES and NO outcome tokens. One winning token ultimately pays $1 and the losing token pays $0. Polymarket’s token framework also allows an equal YES/NO pair to be merged back into $1 of pUSD before resolution.


Buy-both condition


Let:

  • (A_Y(q)) = executable cost of buying (q) YES shares

  • (A_N(q)) = executable cost of buying (q) NO shares

  • (F_Y(q)) and (F_N(q)) = fees

  • (C(q)) = merge, slippage, and safety costs

The trade is potentially profitable when:

q - AY(q) - AN(q) - FY(q) - FN(q) - C(q) > minimumProfit

Example:

YES weighted ask:      0.455
NO weighted ask:       0.525
Raw pair cost:         0.980
Fees per pair:         0.006
Operational buffer:    0.004
Net expected profit:   0.010 per pair

At 100 pairs, expected profit is approximately $1.

That is modest. This business is usually won by repetition, low failure rates, and capital efficiency—not heroic bets.


Sell-both condition

A reverse opportunity exists when combined executable bids exceed $1 after costs.

You can first split pUSD into equal YES and NO inventory, then sell both sides:

$100 pUSD → 100 YES + 100 NO

Splitting is an on-chain operation, so the safer implementation maintains a pre-split inventory instead of trying to split after a transient opportunity appears.


The condition becomes:

BY(q) + BN(q) - q - fees - buffers > minimumProfit

Strategy B: Negative-risk conversion arbitrage

Multi-outcome events can use Polymarket’s negative-risk structure. In these events, a NO token for one outcome can be atomically converted into YES tokens for every other outcome. The event and market metadata expose negative-risk flags, and orders in these markets must be created with the negative-risk option enabled.


For outcome (i), compare:

Cost to buy NO_i

with:

Executable value from selling YES_j for every j ≠ i

A candidate opportunity exists when:

sum(best executable bids for other YES outcomes)
- cost of NO_i
- fees
- conversion cost
- slippage buffer
> minimumProfit

Do not trade placeholder or ambiguous “Other” outcomes automatically. Polymarket’s documentation specifically warns that augmented negative-risk events can contain unnamed placeholders and changing definitions.


Strategy C: Logical implication arbitrage

Suppose event A logically implies event B.

Example:

A: Candidate wins the election
B: Candidate wins their party nomination

If winning the election necessarily requires winning the nomination under both markets’ exact written rules, then:

A ⇒ B

The basket:

NO_A + YES_B

has a minimum terminal payoff of $1:

  • If A occurs, B must occur: payoff = 0 + 1

  • If A does not occur and B occurs: payoff = 1 + 1

  • If neither occurs: payoff = 1 + 0


Thus, combined executable asks below $1 may create an arbitrage.

However, this is where language models become both useful and dangerous.


Use Claude Fable to:

  • Extract market rules

  • Identify potential implication relationships

  • Compare dates, sources, exclusions, and resolution authorities

  • Produce a written proof of the relationship

  • Flag ambiguous wording


Do not allow Claude to approve the trade automatically. A human should approve every new logical relationship template.

One stray clause such as “regardless of subsequent withdrawal” can turn a proof into confetti.


Strategy D: Cross-venue arbitrage

This involves equivalent contracts on two compliant venues.

Do not begin here.


Cross-venue arbitrage adds:

  • Different resolution authorities

  • Different collateral

  • Withdrawal delays

  • Custody risk

  • Different fee models

  • Different market wording

  • Regulatory fragmentation

  • Capital trapped on both sides

Build this only after your Polymarket-only ledger and execution engine are stable.


6. The Production Architecture

Use TypeScript for the first version. It aligns well with Polymarket’s official client, asynchronous streams, and infrastructure ecosystem.


Component 1: Market discovery service

Objective: create a normalized registry of candidate markets.

Polymarket recommends fetching active events with:

active=true&closed=false

Events contain their associated markets. Tradable markets expose CLOB token IDs, and the first token ID is generally the YES token while the second is NO. Always verify outcome ordering from metadata rather than relying on assumptions.


Store:

interface MarketRecord {
  marketId: string;
  conditionId: string;
  eventId: string;
  question: string;
  description: string;
  yesTokenId: string;
  noTokenId: string;
  tickSize: string;
  negRisk: boolean;
  feesEnabled: boolean;
  active: boolean;
  closed: boolean;
  endTime?: string;
  updatedAt: number;
}

Refresh metadata every 5–15 minutes. Do not query market discovery on every book update.


Component 2: Order-book service

Objective: maintain a correct level-two book for every subscribed token.

Use:

  • WebSocket for incremental updates

  • REST snapshots on startup

  • REST snapshots after reconnects

  • Periodic checksum or sanity reconciliation


Polymarket supports batch order-book retrieval for as many as 500 tokens in one request, making batch snapshots preferable to hundreds of individual calls.

Store prices and quantities as decimal strings or arbitrary-precision decimals. Never use raw JavaScript floating-point arithmetic for money.

interface PriceLevel {
  price: Decimal;
  size: Decimal;
}

interface LocalBook {
  tokenId: string;
  bids: PriceLevel[];
  asks: PriceLevel[];
  exchangeTimestamp: number;
  receivedTimestamp: number;
  synchronized: boolean;
}

Component 3: Opportunity engine

Objective: calculate executable edge over multiple depth levels.


The engine should:

  1. Identify valid token relationships.

  2. Generate candidate quantities from cumulative book breakpoints.

  3. Walk both books for each quantity.

  4. Calculate weighted cost.

  5. Calculate fee per individual price level.

  6. Add operational buffers.

  7. Rank opportunities by expected dollars and expected return on capital.

  8. Send candidates to the risk engine.


Core detector:

import Decimal from "decimal.js";

type Level = {
  price: Decimal;
  size: Decimal;
};

type WalkResult = {
  filled: Decimal;
  notional: Decimal;
  fees: Decimal;
  worstPrice: Decimal;
};

function walkAsks(
  asks: Level[],
  desired: Decimal,
  feeRate: Decimal,
): WalkResult {
  let remaining = desired;
  let filled = new Decimal(0);
  let notional = new Decimal(0);
  let fees = new Decimal(0);
  let worstPrice = new Decimal(0);

  for (const level of asks) {
    if (remaining.lte(0)) break;

    const quantity = Decimal.min(level.size, remaining);
    const levelNotional = quantity.mul(level.price);
    const levelFee = quantity
      .mul(feeRate)
      .mul(level.price)
      .mul(new Decimal(1).minus(level.price));

    filled = filled.plus(quantity);
    notional = notional.plus(levelNotional);
    fees = fees.plus(levelFee);
    worstPrice = level.price;
    remaining = remaining.minus(quantity);
  }

  return { filled, notional, fees, worstPrice };
}

type ComplementOpportunity = {
  size: Decimal;
  grossRedemption: Decimal;
  totalCost: Decimal;
  expectedProfit: Decimal;
  edgePerShare: Decimal;
  yesLimitPrice: Decimal;
  noLimitPrice: Decimal;
};

function evaluateComplementBuy(params: {
  yesAsks: Level[];
  noAsks: Level[];
  size: Decimal;
  yesFeeRate: Decimal;
  noFeeRate: Decimal;
  fixedCost: Decimal;
  slippageBufferPerShare: Decimal;
  minimumProfit: Decimal;
}): ComplementOpportunity | null {
  const yes = walkAsks(
    params.yesAsks,
    params.size,
    params.yesFeeRate,
  );

  const no = walkAsks(
    params.noAsks,
    params.size,
    params.noFeeRate,
  );

  if (!yes.filled.eq(params.size) || !no.filled.eq(params.size)) {
    return null;
  }

  const slippageBuffer = params.slippageBufferPerShare.mul(params.size);
  const totalCost = yes.notional
    .plus(no.notional)
    .plus(yes.fees)
    .plus(no.fees)
    .plus(params.fixedCost)
    .plus(slippageBuffer);

  const grossRedemption = params.size;
  const expectedProfit = grossRedemption.minus(totalCost);

  if (expectedProfit.lt(params.minimumProfit)) {
    return null;
  }

  return {
    size: params.size,
    grossRedemption,
    totalCost,
    expectedProfit,
    edgePerShare: expectedProfit.div(params.size),
    yesLimitPrice: yes.worstPrice,
    noLimitPrice: no.worstPrice,
  };
}

Productionize this by testing every cumulative depth breakpoint rather than one predetermined size.


Component 4: Risk engine

Objective: reject attractive trades that can damage the system.


Example initial limits:

risk:
  max_trade_notional_usd: 25
  max_market_exposure_usd: 100
  max_total_unhedged_usd: 15
  max_daily_loss_usd: 20
  max_consecutive_execution_errors: 3
  maximum_book_age_ms: 750
  maximum_clock_skew_ms: 250
  minimum_profit_usd: 0.25
  minimum_edge_per_share: 0.005
  emergency_hedge_slippage: 0.03

These are starting examples, not universal optimum settings.

Risk checks should include:

  • Market is active and tradable

  • Geographic eligibility has been checked

  • Both books are synchronized

  • Book age is acceptable

  • Tick sizes are current

  • Opportunity survives a second calculation

  • Capital and token allowances are sufficient

  • No unresolved order exists for the same market

  • Market exposure remains below limits

  • Daily loss limit has not been reached

  • Estimated hedge loss remains acceptable

  • Market is not too close to a scheduled suspension or resolution

  • Execution system has recently passed a health check


Component 5: Execution engine

Objective: turn an approved opportunity into a fully hedged position.

Use a formal state machine:

DETECTED
   ↓
VALIDATED
   ↓
RESERVED
   ↓
ORDERS_SIGNED
   ↓
LEG_A_SUBMITTED ───→ LEG_A_FAILED → RELEASED
   ↓
LEG_A_FILLED
   ↓
LEG_B_SUBMITTED ───→ LEG_B_FAILED → EMERGENCY_HEDGE
   ↓
LEG_B_FILLED
   ↓
RECONCILED
   ↓
MERGE_PENDING
   ↓
MERGED
   ↓
CLOSED

For a beginner system, use FOK orders for both legs and small sizes. FOK reduces partial-fill complexity at the individual-order level. All Polymarket orders are technically limit orders; an immediately marketable limit order behaves like a market order.


Example official-client pattern:

import {
  ClobClient,
  Side,
  OrderType,
} from "@polymarket/clob-client-v2";

async function submitFokBuy(params: {
  client: ClobClient;
  tokenId: string;
  price: number;
  size: number;
  tickSize: string;
  negRisk: boolean;
}) {
  return params.client.createAndPostOrder(
    {
      tokenID: params.tokenId,
      price: params.price,
      size: params.size,
      side: Side.BUY,
    },
    {
      tickSize: params.tickSize,
      negRisk: params.negRisk,
    },
    OrderType.FOK,
  );
}

The official SDK handles EIP-712 signing and submission. Order creation still requires signing even when authenticated with L2 API credentials.


Which leg goes first?

Prefer the leg with:

  • Less depth

  • Faster recent price movement

  • Greater expected adverse-selection risk

  • Lower emergency unwind liquidity


However, there is no universally safe ordering. Test both approaches from recorded market data.


A stronger architecture maintains inventory on both sides, allowing it to execute from existing positions rather than depending on instantaneous two-leg acquisition.


Component 6: Reconciliation engine

Objective: determine what happened—not what your HTTP response suggested happened.


Reconciliation must compare:

  • Local order records

  • Exchange order status

  • User trade events

  • Wallet token balances

  • pUSD balance

  • Open orders

  • On-chain merge transactions

  • Internal inventory ledger

Every operation needs an idempotency key:

strategy-market-tokenpair-timestamp-sequence

Store:

interface ExecutionRecord {
  executionId: string;
  strategy: string;
  marketId: string;
  state: string;
  expectedSize: string;
  yesFilled: string;
  noFilled: string;
  expectedProfit: string;
  realizedCost: string;
  realizedFees: string;
  mergeTxHash?: string;
  errorCode?: string;
  createdAt: number;
  updatedAt: number;
}

On process restart:

  1. Load every nonterminal execution.

  2. Query live orders.

  3. Query recent trades.

  4. Check wallet balances.

  5. Reconstruct filled quantities.

  6. Hedge, merge, or escalate manually.

  7. Only then restart opportunity detection.


Component 7: CTF operator

Objective: convert balanced inventory back into collateral.

An equal pair can be merged:

100 YES + 100 NO → $100 pUSD

The merge is atomic and reverts when equal quantities are unavailable.

Do not send a merge transaction after every tiny trade. Create thresholds:

merge:
  minimum_pairs: 50
  maximum_wait_minutes: 10
  retain_inventory_pairs: 25

This balances:

  • Capital recycling

  • Transaction overhead

  • Useful inventory retention

  • Operational simplicity


Component 8: Observability

Track:

  • WebSocket update delay

  • REST snapshot latency

  • Book age

  • Opportunities discovered

  • Opportunities rejected by reason

  • Orders submitted

  • Fill rate

  • One-sided fill rate

  • Hedge losses

  • Expected versus realized profit

  • Merge failures

  • Open exposure

  • Daily P&L

  • API errors

  • Reconnect frequency

  • Clock skew

  • Process memory and CPU

Critical alerts:

  • Any unhedged exposure above the limit

  • Three consecutive order errors

  • Reconciliation mismatch

  • Wallet balance mismatch

  • WebSocket stale for more than a few seconds

  • Daily loss threshold reached

  • Private-key or credential loading failure

  • Merge transaction pending abnormally long


7. Repository Structure

Use this structure:

polymarket-arb/
├── CLAUDE.md
├── package.json
├── tsconfig.json
├── .env.example
├── docker-compose.yml
├── src/
│   ├── main.ts
│   ├── config.ts
│   ├── types.ts
│   ├── discovery/
│   │   ├── gamma-client.ts
│   │   └── market-registry.ts
│   ├── market-data/
│   │   ├── websocket-client.ts
│   │   ├── snapshot-client.ts
│   │   ├── order-book.ts
│   │   └── synchronizer.ts
│   ├── strategies/
│   │   ├── complement-buy.ts
│   │   ├── complement-sell.ts
│   │   ├── neg-risk.ts
│   │   └── logical-implication.ts
│   ├── risk/
│   │   ├── limits.ts
│   │   ├── exposure.ts
│   │   └── circuit-breaker.ts
│   ├── execution/
│   │   ├── order-client.ts
│   │   ├── state-machine.ts
│   │   ├── hedger.ts
│   │   └── reconciler.ts
│   ├── settlement/
│   │   ├── merge.ts
│   │   └── transaction-monitor.ts
│   ├── storage/
│   │   ├── postgres.ts
│   │   └── repositories.ts
│   └── telemetry/
│       ├── metrics.ts
│       ├── logger.ts
│       └── alerts.ts
├── tests/
│   ├── unit/
│   ├── integration/
│   ├── replay/
│   └── failure-injection/
└── scripts/
    ├── discover-markets.ts
    ├── record-books.ts
    ├── replay-session.ts
    └── reconcile-account.ts

8. Configure Claude Fable as Your Engineering Team

Create a CLAUDE.md file at the repository root:

# Project: Polymarket Arbitrage Engine

## Mission

Build a deterministic, test-driven Polymarket CLOB V2 arbitrage
engine. Claude assists with engineering but must never be placed
inside the production order decision loop.

## Non-negotiable rules

1. Never commit private keys, API secrets, passphrases, or seed phrases.
2. Never read production secrets.
3. Never enable live trading by default.
4. Use Decimal for money, prices, quantities, fees, and P&L.
5. Every execution action must be idempotent and persisted.
6. Treat multiple orders as non-atomic.
7. No strategy may bypass the centralized risk engine.
8. Every WebSocket reconnect requires a REST resnapshot.
9. Every submitted order must be reconciled against exchange data.
10. Tests must cover partial fills, timeouts, stale books, duplicate
    events, reconnects, and process restarts.
11. The live-trading environment variable must default to false.
12. A failed invariant must trigger the circuit breaker.

## Commands

- npm run typecheck
- npm run lint
- npm test
- npm run test:integration
- npm run test:replay
- npm run shadow

Then initialize the repository:

mkdir polymarket-arb
cd polymarket-arb
git init
npm init -y

npm install \
  @polymarket/clob-client-v2 \
  viem \
  decimal.js \
  ws \
  zod \
  pino \
  pg \
  prom-client

npm install -D \
  typescript \
  tsx \
  vitest \
  eslint \
  @types/node \
  @types/ws

The current official Polymarket installation command uses @polymarket/clob-client-v2 and viem.


Your master Claude prompt

You are the principal engineer for a production-minded prediction-market
arbitrage engine.

Read CLAUDE.md first.

Implement the project incrementally. Do not write the entire application
in one pass.

For the current task:

1. Inspect existing code and tests.
2. State the invariants that must remain true.
3. Propose the smallest coherent change.
4. Implement the change.
5. Add unit tests and failure tests.
6. Run typecheck, lint, and tests.
7. Fix all failures.
8. Summarize files changed, assumptions made, unresolved risks, and the
   next safest task.

Important constraints:

- Use TypeScript strict mode.
- Use Decimal for financial arithmetic.
- Never access production credentials.
- Never add live order submission without an explicit LIVE_TRADING=true
  gate and a second confirmation variable.
- Treat order responses as provisional until reconciled.
- Do not infer cross-market logical equivalence from market titles alone.
- Do not silently weaken a test to make it pass.

Build in controlled Claude sessions

Use one session per subsystem:

  1. Market metadata

  2. Book synchronization

  3. Pure arbitrage calculations

  4. Fee calculator

  5. Risk engine

  6. Simulated execution

  7. Reconciliation

  8. Live client adapter

  9. CTF operations

  10. Deployment and observability

Long agent sessions are impressive until they create twelve mutually reinforcing mistakes. Small verified increments are cheaper than archaeological debugging.


9. Step-by-Step Execution Roadmap

Step 1: Establish compliance and wallet isolation

Objective: ensure the project can legally and safely operate.

Actions:

  • Review Polymarket’s current geographic restrictions.

  • Call the geographic check before enabling trading.

  • Create a dedicated wallet.

  • Fund it with only test capital.

  • Store keys in a secrets manager or restricted environment file.

  • Ensure Claude Code cannot read the production secret location.

  • Create separate development and production configurations.

Time: 2–4 hours Estimated cost: $0–$50 Deliverable: compliance checklist and isolated test wallet Success metric: production key never appears in source, logs, prompts, or shell history


Step 2: Build market discovery

Objective: identify active binary and negative-risk markets.

Actions:

  • Fetch active, non-closed events.

  • Normalize markets and token IDs.

  • Filter enableOrderBook=true.

  • Record fee and negative-risk metadata.

  • Persist all market-rule text.

  • Refresh periodically.

  • Diff metadata changes.

Time: 4–8 hours Cost: negligible Deliverable: searchable local market registry Success metric: registry matches sampled Polymarket pages and contains no duplicate token mappings


Step 3: Build synchronized books

Objective: maintain correct local books.

Actions:

  • Load initial books using batch REST.

  • Subscribe to token IDs via WebSocket.

  • Apply updates in timestamp order.

  • Detect malformed or stale updates.

  • Resnapshot after reconnect.

  • Record raw events for replay.


Time: 8–16 hours Cost: $5–$30 per month for storage and hosting Deliverable: book service with replay logs Success metric: top levels repeatedly match REST snapshots

Polymarket publishes generous but finite API limits. Build around streaming and batch requests rather than careless polling.


Step 4: Implement pure arbitrage mathematics

Objective: calculate edge without exchange side effects.

Actions:

  • Implement depth walking.

  • Implement per-level fees.

  • Generate candidate quantities.

  • Add fixed and per-share buffers.

  • Add minimum-dollar and minimum-edge thresholds.

  • Test empty books and malformed prices.

  • Test extreme prices and changing tick sizes.


Time: 6–12 hours Cost: $0 Deliverable: deterministic opportunity library Success metric: 100% passing unit tests with hand-calculated fixtures


Step 5: Build a realistic simulator

Objective: discover whether theoretical opportunities survive latency.

Actions:

  • Record live market data.

  • Replay at original timing.

  • Insert 50 ms, 100 ms, 250 ms, 500 ms, and 1,000 ms execution delays.

  • Simulate queue depletion.

  • Reject fills when displayed depth disappears.

  • Simulate one-leg failure.

  • Calculate hedge cost.

  • Produce expected-versus-realized distributions.


Time: 8–20 hours Cost: $0–$20 Deliverable: replay engine and performance report Success metric: strategy remains positive after conservative execution assumptions


Step 6: Implement shadow mode

Objective: operate continuously without signing orders.

Actions:

  • Run full discovery and risk logic.

  • Create simulated execution records.

  • Log intended orders.

  • Reconcile against subsequent trades and books.

  • Estimate whether the orders would have filled.

  • Measure false-positive opportunities.

Time: 7–14 calendar days Cost: approximately $20–$100 infrastructure Deliverable: shadow-mode dataset Success metric: at least several hundred observed candidates and zero unresolved accounting states


Step 7: Add authenticated trading

Objective: submit tiny live orders safely.

Polymarket uses L1 private-key authentication for credential derivation and local order signing, while L2 credentials authenticate CLOB actions such as posting and cancelling signed orders.

Actions:

  • Derive API credentials securely.

  • Implement balance and allowance checks.

  • Implement FOK order submission.

  • Implement order cancellation.

  • Add user-trade monitoring.

  • Persist before every external side effect.

  • Add manual kill switch.

  • Add automatic daily-loss circuit breaker.

Time: 8–16 hours Cost: test capital plus infrastructure Deliverable: live adapter behind feature flags Success metric: 20–50 tiny executions reconcile correctly


Step 8: Add merge and inventory management

Objective: recycle capital and prevent inventory drift.

Actions:

  • Detect equal token quantities.

  • Retain configured working inventory.

  • Merge excess pairs.

  • Monitor transaction confirmation.

  • Reconcile pUSD received.

  • Retry safely without duplicate operations.

Time: 6–12 hours Cost: network and relayer costs Deliverable: automated merge workflow Success metric: token balances and internal ledger remain equal after every completed cycle


Step 9: Graduate capital slowly

Example progression:

Phase 1: $1–$5 maximum per trade
Phase 2: $10 maximum per trade
Phase 3: $25 maximum per trade
Phase 4: $50 maximum per trade
Phase 5: Dynamic sizing based on depth and observed fill quality

Do not graduate based on calendar time. Graduate when metrics earn it.

Required gates:

  • No unexplained ledger differences

  • One-sided fill rate below threshold

  • Hedge losses within assumptions

  • Stable uptime

  • No secret-handling incidents

  • Realized P&L reasonably tracks modeled P&L


10. Tool Stack

Essential


Claude Code with Fable 5 Use for repository-level implementation, test generation, refactoring, and incident analysis.


Polymarket TypeScript CLOB V2 client Use for authentication, signing, market data, order management, and trading. Essential.


TypeScript Use strict types to make invalid financial states harder to represent.

Decimal.js Use for every financial calculation.


PostgreSQL Use as the source of truth for orders, executions, balances, opportunities, and state transitions.


Pino Use for structured JSON logging.


Vitest Use for deterministic unit, integration, and replay tests.


Strongly recommended


Redis Use for short-lived locks, rate limiting, and book fan-out. PostgreSQL should remain the durable ledger.


Prometheus and Grafana Use for latency, exposure, error, and profitability dashboards.


Docker Use for reproducible deployment.


Sentry or equivalent error tracking Use for exception grouping and release correlation.


PagerDuty, Opsgenie, Telegram, or Slack alerts Use for exposure and circuit-breaker notifications.


Optional


Claude Agent SDK Anthropic’s Agent SDK can run programmable coding agents in TypeScript or Python. Use it for offline maintenance workflows such as log analysis or automated test-case generation—not live trading.


ClickHouse Useful once you collect hundreds of millions of book events.


NATS or Kafka Useful only when one-process or Redis-based event flow becomes insufficient.

Terraform Useful when infrastructure becomes multi-environment or multi-region.


11. Revenue Potential

Revenue is not guaranteed. Arbitrage capacity is constrained by opportunity frequency, available depth, competition, latency, execution quality, fees, and capital turnover.

A useful model is:

Monthly strategy P&L
≈ deployed capital
× monthly capital-turnover multiple
× net captured edge

“Net captured edge” must already include fees, failed legs, hedge losses, and operational costs.


Conservative case

  • Capital: $5,000

  • Monthly turnover: 2×

  • Net captured edge: 0.20%

  • Hypothetical monthly P&L: $20

  • Hypothetical annual P&L: $240


What must be true:

  • The strategy remains slightly positive

  • Failures stay rare

  • Infrastructure costs remain low

The lesson is not that the business is useless. The lesson is that tiny capital plus tiny edges produces tiny dollars.


Moderate case

  • Capital: $25,000

  • Monthly turnover: 5×

  • Net captured edge: 0.30%

  • Hypothetical monthly P&L: $375

  • Hypothetical annual P&L: $4,500


What must be true:

  • Sufficient opportunities exist

  • The bot captures most modeled edge

  • Capital is not trapped in unresolved exposure


Aggressive case

  • Capital: $100,000

  • Monthly turnover: 10×

  • Net captured edge: 0.35%

  • Hypothetical monthly P&L: $3,500

  • Hypothetical annual P&L: $42,000


What must be true:

  • Market depth supports larger size

  • Your own execution does not erase the discrepancy

  • Operational and counterparty exposure remains controlled

  • Competition does not compress the opportunity


High-performance case

  • Capital: $250,000

  • Monthly turnover: 20×

  • Net captured edge: 0.40%

  • Hypothetical monthly P&L: $20,000

  • Hypothetical annual P&L: $240,000


This is not a beginner projection. It assumes substantial capacity, excellent uptime, sophisticated inventory management, and durable distribution or latency advantages.


The danger in arbitrage forecasting is assuming that a percentage scales indefinitely.

It rarely does.

Capital is useful only until it becomes larger than the opportunity. After that, it is luggage.

12. Monetizing the Technology Beyond Trading

The bot itself can become a product, but financial software introduces legal, contractual, and reputational obligations. Obtain qualified legal advice before executing trades for others, custodying funds, selling regulated advice, or operating in restricted locations.


Entry-level offer

Market-dislocation alert dashboard

  • Read-only

  • No wallet connection

  • Displays gross and estimated net spreads

  • $29–$99 per month


Premium offer

Professional arbitrage research terminal

  • Depth-aware calculations

  • Fee modeling

  • Historical opportunity replay

  • Webhooks

  • $250–$1,000 per month


Recurring developer offer

Hosted market-data and normalized relationship API

  • Clean market metadata

  • Synchronized books

  • Fee-normalized quotes

  • Usage-based pricing


Done-for-you offer

Private deployment and infrastructure setup

  • Customer controls wallet and credentials

  • You deploy software and monitoring

  • $5,000–$25,000 setup plus maintenance


Advisory offer

Prediction-market execution architecture review

  • Security review

  • State-machine review

  • Risk-limit design

  • Replay-analysis audit

  • $2,500–$15,000 per engagement


AI-powered offer

Market-rule relationship research assistant

Claude extracts:

  • Resolution criteria

  • Date dependencies

  • Logical implications

  • Potential contradictions

  • Required human-review points


The product recommends relationships. It does not execute trades.


High-ticket offer

Institutional-grade execution and risk platform


Features:

  • Multi-wallet segregation

  • Role-based access

  • Audit logs

  • Hardware-backed signing

  • Disaster recovery

  • Custom reconciliation

  • Service-level monitoring

Price according to integration complexity, not wishful thinking.


13. Go-to-Market Plan for the Software

Best segments

  • Quantitative developers

  • Prediction-market research firms

  • Market makers

  • Crypto trading teams

  • Financial-data providers

  • Academic forecasting groups

  • Analysts building read-only tools


Positioning

Bad positioning:

“AI-powered Polymarket bot that makes passive income.”

That sentence attracts regulators, skeptics, and customers you do not want.

Better positioning:

“Depth-aware prediction-market execution infrastructure with deterministic risk controls and complete reconciliation.”

Messaging angles

  • “Most arbitrage dashboards calculate the headline spread. We calculate whether the displayed depth can actually pay you.”

  • “Every fill accounted for. Every hedge measured. Every unexplained balance stops the system.”

  • “A trading bot should not merely find opportunities. It should survive them.”

  • “Replay yesterday’s order books before risking today’s capital.”


Content strategy

Publish:

  • Postmortems of simulated leg failures

  • Fee-calculation explainers

  • Order-book depth visualizations

  • Studies of gross versus executable spread

  • WebSocket recovery patterns

  • Market-rule ambiguity examples

  • Open-source calculation utilities


Lead magnets

  • Arbitrage fee calculator

  • Polymarket CLOB V2 starter repository

  • Book-replay dataset

  • Risk-limit worksheet

  • Market-equivalence review checklist


Funnel

Technical article
→ free calculator
→ email sequence
→ read-only dashboard trial
→ developer plan
→ professional deployment

Trust is the actual product. The dashboard is merely where you display it.


14. Deployment Plan

First 24 hours

Priorities:

  • Install Claude Code

  • Create repository

  • Add CLAUDE.md

  • Install dependencies

  • Create strict TypeScript configuration

  • Implement market-registry types

  • Fetch and print active markets

  • Commit a clean baseline

Deliverable: read-only market-discovery CLI

Do not add private keys.


First 7 days

Build:

  • Market registry

  • Batch snapshots

  • WebSocket books

  • Recorder

  • Complement detector

  • Fee calculator

  • Unit tests

  • Replay command

Metrics:

  • Book freshness

  • Reconnect rate

  • Detected gross edge

  • Detected net edge

  • Maximum theoretical size

  • Opportunity duration

Decision point: do executable opportunities exist after conservative fees and latency?


First 30 days

Build:

  • Shadow execution

  • Risk engine

  • State machine

  • Reconciliation database

  • Failure injection

  • Dashboards

  • Alerts

  • CTF merge prototype


Metrics:

  • Candidate count

  • Simulated fill rate

  • One-sided fill estimate

  • Median opportunity lifetime

  • Expected hedge cost

  • Net simulated P&L

  • Maximum simulated drawdown

Decision point: is the observed edge robust enough to justify test capital?


First 90 days

Operate:

  • Micro live trading

  • Manual supervision

  • Daily reconciliation

  • Weekly failure review

  • Gradual sizing

  • Negative-risk research

  • Infrastructure hardening

Metrics:

  • Realized versus expected edge

  • Fill ratio

  • Hedge-loss ratio

  • Return on deployed capital

  • System uptime

  • Unexplained balance incidents

  • Drawdown

Decision point: scale, change strategy, or shut it down.

Shutting down a weak strategy is not failure. It is capital preservation with excellent paperwork.


First 12 months

Potential expansion:

  • Inventory-backed execution

  • Maker-first strategies

  • Negative-risk conversions

  • Human-approved logical relationships

  • Multi-region read infrastructure

  • Hardware-backed signing

  • Institutional monitoring

  • Commercial data products

Do not expand merely because the roadmap contains empty boxes. Expand when a measured bottleneck justifies it.


15. Operating System After Launch

Daily

  • Review open exposure

  • Reconcile balances

  • Review failed orders

  • Check WebSocket gaps

  • Verify current fee metadata

  • Review realized versus modeled P&L

  • Confirm circuit breakers

  • Merge excess inventory

  • Check platform changelog


Weekly

  • Replay the worst executions

  • Recalculate latency assumptions

  • Review hedge losses

  • Audit new market relationships

  • Rotate or verify credentials

  • Test disaster recovery

  • Update dependencies in a staging branch

  • Run full integration tests


Monthly

  • Review capital efficiency

  • Remove unproductive markets

  • Re-estimate minimum edge

  • Analyze capacity by market category

  • Review infrastructure spending

  • Perform a secret-access audit

  • Test process restart during open exposure

  • Produce a full accounting snapshot


Core KPIs

  • Net realized P&L

  • Net edge per completed pair

  • Fill-adjusted opportunity conversion

  • Unhedged exposure duration

  • Emergency hedge cost

  • Maximum drawdown

  • Return on deployed capital

  • Capital turnover

  • Reconciliation mismatch count

  • Book-data uptime

  • Order error rate

  • Strategy P&L by category


16. Common Failure Points


Mistake 1: Using top-of-book prices

Why it happens: the visible spread is seductive.

What it looks like: profitable calculations at one share, losses at actual size.

What to do: walk every price level and calculate the largest profitable quantity.


Mistake 2: Ignoring fees

Why it happens: old tutorials claim all markets are fee-free.

What it looks like: the model earns money while the account loses it.

What to do: query fee settings per market and calculate fees per executed price level.


Mistake 3: Treating two orders as one transaction

Why it happens: both submission promises begin at nearly the same time.

What it looks like: one fill, one failure, one unexpected opinion about politics.

What to do: implement leg-risk reserves, emergency hedging, and reconciliation.


Mistake 4: Letting the LLM touch secrets

Why it happens: convenience quietly graduates into recklessness.

What it looks like: private keys in logs, prompts, or command history.

What to do: isolate production signing, minimize wallet balances, and deny agent access to secret locations.


Mistake 5: Backtesting with midpoint prices

Why it happens: midpoint history is easy to download.

What it looks like: magnificent historical results that cannot be executed.

What to do: record level-two books and simulate latency and depth consumption.


Mistake 6: Trading ambiguous logical relationships

Why it happens: the market titles look equivalent.

What it looks like: the markets resolve under different dates, sources, or exceptions.

What to do: compare the complete rules and require human approval.


Mistake 7: No restart recovery

Why it happens: developers test the happy path while the process remains alive.

What it looks like: an order fills during a crash and disappears from local memory.

What to do: persist state before submission and reconstruct every nonterminal execution on startup.


Mistake 8: Scaling after a few winning trades

Why it happens: luck wears a convincing suit.

What it looks like: ten successful $5 trades followed by a disastrous $5,000 exposure.

What to do: scale only after statistically meaningful execution data and fault testing.


Mistake 9: Hard-coding platform behavior

Why it happens: documentation feels permanent when read on a quiet afternoon.

What it looks like: tick-size, fee, collateral, or API changes silently break execution.

What to do: query metadata, pin dependencies, monitor changelogs, and fail closed.


17. Advanced Strategies


Inventory-backed arbitrage

Maintain balanced token inventory so you can immediately sell overpriced pairs or complete hedges without waiting for a new split transaction.

This improves responsiveness but adds inventory capital and monitoring requirements.


Maker-taker hybrids

Post a post-only maker order on one side. When filled, immediately hedge the complementary side as a taker.

Potential advantages:

  • No maker fee

  • Possible rebate eligibility

  • Better entry price


Risks:

  • Adverse selection

  • Uncertain fill timing

  • One-sided exposure

  • More complex inventory skew


Polymarket currently offers maker rebates in fee-enabled categories. Treat rebates as a bonus, not the core edge, because program parameters can change.


Adaptive edge thresholds

Set minimum edge according to:

  • Recent price volatility

  • Book depth

  • p99 order latency

  • Historical hedge loss

  • Market category

  • Time to resolution

  • Recent reconnects

  • Available capital

  • Strategy confidence


Example:

requiredEdge
= baseEdge
+ p99Slippage
+ p99HedgeLoss
+ dataQualityPenalty
+ volatilityPenalty

Data moat

Your most valuable asset may not be the bot.

It may be a database containing:

  • Every detected opportunity

  • Full order-book context

  • Opportunity lifetime

  • Simulated execution outcomes

  • Realized fill quality

  • Hedge costs

  • Market-category behavior

  • Failure patterns


Competitors can copy code. They cannot instantly copy twelve months of correctly labeled execution data.


Claude-powered offline research

Use Fable to review:

  • New API documentation

  • Changelog differences

  • Incident logs

  • Unusual market-rule language

  • Test-coverage gaps

  • Repeated rejection reasons

  • Strategy degradation

Require structured output:

{
  "finding": "...",
  "evidence": ["..."],
  "risk_level": "low|medium|high",
  "suggested_test": "...",
  "requires_human_approval": true
}

No model-generated recommendation should directly modify production risk limits.


Signing moat

At higher capital levels:

  • Separate detection from signing

  • Use a narrow signing service

  • Permit only validated order schemas

  • Add notional ceilings inside the signer

  • Use independent kill switches

  • Consider hardware-backed key custody

  • Maintain immutable audit logs

The signing service should be deliberately boring. Boring is an underrated security feature.


18. Final Action Checklist

Today

  • Verify geographic eligibility.

  • Install Claude Code.

  • Create the repository and CLAUDE.md.

  • Install the official CLOB V2 client.

  • Build read-only market discovery.

  • Do not fund the bot.


This week

  • Build synchronized order books.

  • Record live data.

  • Implement depth-aware complement calculations.

  • Add market-specific fees.

  • Write failure tests.

  • Start replay analysis.


This month

  • Run shadow mode.

  • Build the risk engine.

  • Implement the execution state machine.

  • Build reconciliation.

  • Test restarts and partial failures.

  • Produce a shadow-performance report.


Before live deployment

  • Dedicated wallet

  • Restricted production secrets

  • Geographic check

  • Live-trading feature flags

  • Daily loss limit

  • Maximum exposure limit

  • Book-staleness guard

  • Emergency hedge path

  • Manual kill switch

  • Automated reconciliation

  • Alerting

  • Micro-size limits

  • Documented recovery procedure


Never compromise

  • No floating-point money calculations

  • No unresolved orders ignored

  • No stale books traded

  • No automatic semantic relationship approval

  • No private keys exposed to Claude

  • No scaling based on enthusiasm

  • No bypassing jurisdictional restrictions

  • No belief that “arbitrage” means “incapable of losing”


The Final Playbook

The fastest credible path is not to ask Claude Fable to generate a complete bot and immediately connect it to a funded wallet.


The fastest credible path is:

  1. Let Fable build a typed, test-driven market-data engine.

  2. Record real order books.

  3. Prove the calculations on replay.

  4. Run the complete system without signing orders.

  5. Implement reconciliation before execution.

  6. Trade trivial amounts.

  7. Scale only when observed fills validate the model.

  8. Turn every failure into a permanent automated test.


The highest-leverage work is not the scanner. It is the layer that answers the question:

“What precisely happens when only half of our beautiful idea becomes real?”

Build that layer first.


A profitable arbitrage system is not a clever equation wrapped in an API client. It is a disciplined machine that converts temporary inconsistency into settled collateral while refusing every opportunity it cannot control.


The market does not reward the bot that notices the most discrepancies. It rewards the bot that survives the distance between noticing and getting paid.


Appendix:



 
 
 
bottom of page