DEV Community

Cover image for Polymarket Market Making Bot(TWAP Edition): Build a Python Liquidity Engine
Bo$onaX
Bo$onaX

Posted on

Polymarket Market Making Bot(TWAP Edition): Build a Python Liquidity Engine

Build a Polymarket market making bot in Python with order-book quoting, inventory controls, liquidity rewards, monitoring, and production risk management.

Polymarket Market Making Bot: Build a Python Liquidity Engine

A Polymarket market making bot is not simply a script that places a buy order below the current price and a sell order above it. A real market-making system continuously manages quotes, inventory, order-book changes, fills, adverse selection, API failures, and market-specific liquidity incentives.

For Polymarket developers, the core challenge is maintaining competitive resting liquidity without accidentally building a machine that repeatedly buys when informed traders are selling and sells when informed traders are buying.

Polymarket provides a central limit order book (CLOB), and its official market-maker documentation specifically covers quoting, inventory management, and liquidity rewards. The recommended production approach is to use the official SDK clients rather than manually implementing order signing and authentication.

What You'll Learn

In this article, you will learn how to design a market-making engine that:

  • Reads Polymarket market data and order books
  • Calculates a fair-value estimate
  • Generates bid and ask quotes
  • Prevents crossed markets
  • Tracks inventory exposure
  • Refreshes stale quotes
  • Handles fills and partial fills
  • Evaluates liquidity reward configurations
  • Adds logging, retries, monitoring, and kill switches

How a Polymarket Market Making Bot Works

A simple market maker starts with a fair probability estimate:

fair_value = 0.50
Enter fullscreen mode Exit fullscreen mode

It then quotes around that estimate:

bid = 0.48
ask = 0.52
Enter fullscreen mode Exit fullscreen mode

The theoretical gross spread is:

ask - bid = 0.04
Enter fullscreen mode Exit fullscreen mode

But the displayed spread is not profit. A market maker can lose money through adverse selection, inventory imbalance, stale quotes, and execution costs.

The real system therefore needs multiple components:

flowchart LR
    A[Market Discovery] --> B[Order Book Feed]
    B --> C[Fair Value Model]
    C --> D[Quote Engine]
    D --> E[Risk Checks]
    E --> F[Polymarket CLOB]
    F --> G[Fills and Order State]
    G --> H[Inventory Manager]
    H --> C
    G --> I[Monitoring]

The official Python SDK is currently py-clob-client-v2, and the official documentation shows a ClobClient configured against https://clob.polymarket.com on Polygon chain ID 137.

Step 1: Build the Quote Model

A practical quote function should account for inventory.

from decimal import Decimal


def calculate_quotes(
    fair_value: Decimal,
    base_spread: Decimal,
    inventory: Decimal,
    inventory_limit: Decimal,
):
    inventory_ratio = inventory / inventory_limit

    # Move quotes lower when inventory is too long.
    inventory_adjustment = inventory_ratio * Decimal("0.02")

    bid = fair_value - base_spread / 2 - inventory_adjustment
    ask = fair_value + base_spread / 2 - inventory_adjustment

    bid = max(Decimal("0.01"), bid)
    ask = min(Decimal("0.99"), ask)

    if bid >= ask:
        raise ValueError("Invalid quote: crossed or zero spread")

    return bid, ask
Enter fullscreen mode Exit fullscreen mode

If the bot becomes too long YES shares, the inventory adjustment moves both quotes lower. This makes buying less attractive and selling more attractive.

That is much safer than blindly maintaining symmetric quotes.

Step 2: Read the Order Book

A market maker should react to the live market rather than repeatedly polling blindly.

Polymarket provides REST and WebSocket infrastructure for market data, while its market-maker documentation explicitly recommends WebSocket monitoring for order books. Public SDK methods can also fetch markets without signing credentials.

A simplified design is:

def calculate_midpoint(best_bid, best_ask):
    if best_bid is None or best_ask is None:
        return None

    return (best_bid + best_ask) / 2
Enter fullscreen mode Exit fullscreen mode

The midpoint can be one input into fair value, but a production bot should not automatically assume that the midpoint is the true probability.

A stronger model might combine:

  • Current best bid and ask
  • Order-book depth
  • External market data
  • Related Polymarket markets
  • Time remaining until resolution
  • Inventory exposure
  • Volatility of the underlying information

Step 3: Manage Orders

A production market maker needs an order lifecycle:

  1. Calculate desired quotes
  2. Compare them with active orders
  3. Cancel or replace stale quotes
  4. Submit new limit orders
  5. Track fills
  6. Recalculate inventory

Do not continuously cancel and repost everything without reason. That creates unnecessary API traffic and operational complexity.

Polymarket publishes endpoint-specific rate limits, including separate limits for market data and trading operations. Excess traffic may be throttled or queued, so quote refresh logic should use state changes rather than uncontrolled polling loops.

A useful pattern is exponential backoff:

import logging
import time


def retry(operation, attempts=5):
    delay = 0.5

    for attempt in range(attempts):
        try:
            return operation()
        except Exception as exc:
            logging.warning(
                "Operation failed: %s. Retrying in %.1fs",
                exc,
                delay,
            )

            if attempt == attempts - 1:
                raise

            time.sleep(delay)
            delay *= 2
Enter fullscreen mode Exit fullscreen mode

Inventory Management Is the Real Strategy

Many beginners focus entirely on spread.

Professional market making is primarily an inventory problem.

Suppose your bot buys a large amount of YES inventory. Even if your spread is positive, you are now exposed to the probability moving against that position.

A simple inventory rule might be:

MAX_POSITION = 100

if yes_inventory > MAX_POSITION:
    disable_new_yes_bids = True
Enter fullscreen mode Exit fullscreen mode

More advanced systems dynamically:

  • Widen the spread as inventory increases
  • Skew the reservation price
  • Reduce quote size
  • Disable one side temporarily
  • Hedge correlated exposure where appropriate

Polymarket's market-maker documentation also warns against crossed markets, where a bid is above an ask. This can create immediate losses on fills, so quote validation must occur before every submission.

Liquidity Rewards: Useful, but Not a Trading Edge

Polymarket currently operates liquidity incentive mechanisms for makers that provide resting liquidity. Eligible configurations include market-specific parameters such as maximum spread and minimum incentive size. The documentation states that rewards are designed to favor tighter, deeper, and more balanced liquidity, with rewards distributed daily.

A reward-aware bot should inspect:

  • rewards_max_spread
  • rewards_min_size
  • Current reward configuration
  • Market competitiveness
  • Whether two-sided quoting is economically viable

Do not build a bot that chases rewards without measuring adverse selection. A reward can improve economics while the underlying inventory strategy still loses money.

Production Failure Modes

The most dangerous mistakes include:

Stale quotes

Your fair value changes, but your old orders remain on the book.

Inventory accumulation

One-sided fills can slowly turn a neutral market maker into a directional trader.

Crossed quotes

Always enforce:

bid < ask
Enter fullscreen mode Exit fullscreen mode

Partial-fill errors

Never assume an order is either completely filled or completely unfilled.

API or network failure

If the bot loses connectivity, it must know whether to cancel orders, pause quoting, or enter a degraded mode.

False profitability

A backtest that only measures spread capture but ignores inventory mark-to-market is incomplete.

Performance and Monitoring

Track at least:

  • Current inventory
  • Open orders
  • Quote age
  • Fill rate
  • Order rejection rate
  • Cancel errors
  • REST/WebSocket failures
  • Realized P&L
  • Mark-to-market P&L
  • Reward estimates separately from trading P&L

Keep the following states in persistent storage:

market_id
token_id
active_orders
inventory
last_fill
last_quote_time
strategy_state
Enter fullscreen mode Exit fullscreen mode

A restart without persistent state can cause duplicate orders or incorrect inventory calculations.

Security Considerations

Never hardcode secrets.

import os

PRIVATE_KEY = os.environ.get("PRIVATE_KEY")

if not PRIVATE_KEY:
    raise RuntimeError("PRIVATE_KEY is not configured")
Enter fullscreen mode Exit fullscreen mode

Keep signing keys outside the repository. Use environment variables or a dedicated secret-management system, restrict operational wallet exposure, and implement a manual or automated kill switch.

Practical Strategy Example

A simple strategy can:

  1. Select a liquid market.
  2. Estimate fair value from the order book.
  3. Quote a small two-sided spread.
  4. Shift the quotes according to inventory.
  5. Refresh only when the desired quote materially changes.
  6. Pause when inventory exceeds risk limits.
  7. Record every fill and state transition.

This is a market-making engine, not a guaranteed-profit bot.

Polymarket's current documentation also distinguishes makers from takers in its fee structure, with fees determined per market and applied at match time. A bot should therefore retrieve and respect current market information rather than hardcoding fee assumptions.

Advanced Improvements

Once the basic system works, improve it with:

  • Order-book imbalance signals
  • Volatility-adjusted spreads
  • Queue-position modeling
  • Dynamic quote sizing
  • Multi-market inventory controls
  • Market-specific reward optimization
  • WebSocket-first architecture
  • Persistent event sourcing
  • Separate risk and execution processes

The best architecture is usually one where signal generation, quote generation, execution, inventory accounting, and risk management are separate components.

Frequently Asked Questions

Is market making on Polymarket profitable?

It can be profitable or unprofitable. Results depend on spreads, adverse selection, inventory risk, liquidity, execution, and any applicable incentive programs.

Do I need Python to build a Polymarket market-making bot?

No, but Python is practical for research, automation, and prototyping. Polymarket also provides official developer tooling for other languages.

Should I use REST polling only?

For a serious market maker, continuously polling everything is generally a weak architecture. Use the available real-time market-data infrastructure where appropriate and reserve REST for snapshots, recovery, and order operations.

What is the biggest market-making risk?

Inventory risk combined with adverse selection. A bot can repeatedly get filled when its quoted probability is stale.

Can I optimize only for liquidity rewards?

No. Rewards should be evaluated as one component of total economics, not as a substitute for risk management.

Conclusion

A Polymarket market making bot should be treated as a real trading system.

The hard part is not placing two orders around a midpoint. The hard part is deciding when those orders should exist, how much inventory they should accumulate, when they should move, and when the system should stop quoting entirely.

Start with small size, persistent state, conservative inventory limits, strong monitoring, and extensive testing before exposing meaningful capital.

Educational and trading-risk disclaimer: This article is for educational and software-development purposes only. Market making involves substantial financial risk, including adverse selection, inventory losses, execution failures, and losses of capital. Nothing here is financial advice or a guarantee of profitability.

Useful Resources

Suggested Internal Links

  1. Polymarket Trading Bots in 2026: The Developer's Guide
    Anchor: how to build a Polymarket trading bot
    Why: Broad foundation article for developers entering the ecosystem.

  2. Polymarket Bot Position Sizing
    Anchor: Polymarket position sizing and risk limits
    Why: Extends the inventory-management discussion.

  3. How to Automatically Discover New Polymarket Markets
    Anchor: automatically discover Polymarket markets
    Why: Useful for building automated market-selection pipelines.

  4. Polymarket Momentum Spike Arbitrage Bot
    Anchor: Polymarket momentum trading strategies
    Why: Connects market making with directional execution research.

  5. Polymarket Order Book Data and Market Microstructure
    Anchor: Polymarket order book analysis
    Why: Natural next step for improving quote models.

  6. Building Polymarket Trading Bots with Python
    Anchor: Polymarket Python bot architecture
    Why: Connects the strategy to implementation.

  7. Polymarket TWAP Trading Strategies
    Anchor: Polymarket TWAP market analysis
    Why: Provides a complementary market-data and quantitative strategy topic.

About the Author

Bo$onaX

I write about Polymarket trading bots, prediction-market infrastructure, algorithmic trading, Python automation, Web3 development, and quantitative strategies.

Contact:
Github: https://github.com/n9xdev/poly-alpha-lab
Youtube: https://youtube.com/@bosonax
X: https://x.com/xxniiinxx
Telegram: https://t.me/bosonax
Gmail: mailto:dylandevera91928@gmail.com

Top comments (0)