Building a Polymarket trading bot is not only about finding a strategy that produces profitable signals.
The harder part starts after the signal.
A real automated trading system has to deal with changing order-book prices, partial fills, execution costs, open exposure, failed trades, stale data, repeated losses, gas availability, and the difference between what the bot thinks happened and what actually happened.
That is the problem I wanted to work on with Polymarket Trading Bot v3.2.
The project is an open-source automated trading system for Polymarket with strategy execution, risk management, execution protection, monitoring, and backtesting.
GitHub:
https://github.com/casatrickdev/polymarket-trading-bot
A Polymarket bot needs more than a trading strategy
A simple trading bot can look like this:
Market Data
↓
Strategy
↓
Buy / Sell
That is enough for a prototype.
A more complete automated trading system looks closer to:
Market Data
↓
Strategy Signal
↓
Risk Checks
↓
Position Sizing
↓
Protected Order
↓
Execution
↓
Position / Exposure Tracking
↓
Monitoring
↓
Recovery
The difference is important.
A strategy can be correct while the actual trade still goes wrong.
For example:
- the price changes between signal generation and execution
- an arbitrage leg fills only partially
- fees eliminate the expected edge
- exposure becomes larger than intended
- a copied trade is already stale
- the wallet does not have enough gas
- the system continues trading after a sequence of losses
So the bot has to treat execution and risk as part of the trading system, not as optional additions.
What changed in v3.2?
The latest version focuses heavily on execution safety and risk controls.
The release includes fee-aware profit checks, price-protected orders, sequential arbitrage execution, improved hedging, stale-trade filtering, exposure caps, a wallet circuit breaker, backtesting, Polygon gas monitoring, and loss-streak protection.
The result is a system that tries to answer a bigger question than:
“Should I trade?”
It also asks:
“Can I safely execute this trade right now?”
1. Fee-aware Polymarket trading
A price difference is not automatically a profitable trade.
Execution costs matter.
The bot now calculates arbitrage and DipArb opportunities while accounting for:
- taker fees
- gas costs
- minimum net-profit requirements
This means a signal can be rejected even when the gross price relationship looks attractive.
That is an important distinction for automated trading:
Gross Opportunity
↓
- Trading Fees
- Gas
↓
Net Opportunity
↓
Profit Threshold
↓
Execute / Skip
The strategy is therefore evaluated against the cost of actually trading rather than only the theoretical price difference.
2. Price-protected orders
One of the easiest ways for an automated trading system to behave unexpectedly is to submit an order without sufficient price protection.
Markets move.
The bot now derives worst-price caps or floors from the live order book before sending market orders.
The idea is straightforward:
Live Order Book
↓
Current execution conditions
↓
Worst acceptable price
↓
Order
Instead of treating the market price as static, the execution layer explicitly accounts for the price at which the system is still willing to trade.
3. Sequential arbitrage execution
Arbitrage introduces another problem.
Suppose the system wants to buy both YES and NO.
A naive implementation might submit both orders at approximately the same time.
That creates a race.
What happens if one order fills and the other does not?
Now the bot has exposure that was not part of the intended position.
In v3.2, the arbitrage legs execute sequentially, with unwind and reconciliation logic around partial fills.
Conceptually:
YES / Leg 1
↓
Actual Fill
↓
Validate
↓
NO / Leg 2
↓
Actual Fill
↓
Reconcile
The system is no longer treating the two orders as if they were guaranteed to fill together.
4. Handling partial fills
Partial fills are one of those problems that look small in a prototype and become important in an automated system.
The intended position might be:
100 shares
But actual execution could be:
60 filled
40 remaining
That means the system needs to know what it actually owns rather than what it originally requested.
The bot's execution logic therefore works around:
- actual fills
- incomplete legs
- residual exposure
- reconciliation
- unwind behavior
This is one reason execution state needs to be treated separately from strategy state.
5. DipArb execution protection
The DipArb strategy watches short-duration crypto markets for rapid price movements.
The current implementation includes:
- BTC and ETH 15-minute markets
- rapid price-move detection
- a first-leg entry
- an opposite-side hedge
- shorter hedge timeout
- stop-loss behavior
- 1:1 hedge requirements based on actual fills
The important engineering point is that the hedge is not based only on the intended order quantity.
It is tied to what actually filled.
That matters because:
Requested quantity ≠ Actual quantity
in a real execution environment.
6. Filtering stale copy-trading signals
Copy trading creates another timing problem.
A profitable-looking wallet transaction may already be several seconds old by the time the bot sees it.
v3.2 skips stale whale prints and re-quotes the entry against the current market, with spread, premium, and liquidity checks.
The flow becomes:
Observed Wallet Trade
↓
Freshness Check
↓
Current Order Book
↓
Spread / Liquidity Checks
↓
Entry Decision
This prevents the system from blindly treating an old trade as a current market opportunity.
7. Six-layer risk management
The trading strategy is only one part of capital protection.
The bot now uses six layers of risk controls:
| Protection | Default |
|---|---|
| Daily loss limit | 5% |
| Monthly loss limit | 15% |
| Maximum drawdown | 25% |
| Total-loss halt | 40% |
| Loss-streak pause | 6 losses |
| Total exposure cap | 30% |
These controls are intended to operate at different levels.
For example:
Trade
↓
Position Limit
↓
Market Exposure
↓
Loss Streak
↓
Daily Loss
↓
Drawdown
↓
Total Loss
This creates several opportunities to stop trading before one failure becomes a much larger problem.
8. Dynamic position sizing
Position size is also connected to recent performance.
The default system starts at 2% of configured capital and changes position size according to consecutive wins or losses, subject to the configured cap.
The basic concept is:
Winning streak
↓
Potentially larger size
Losing streak
↓
Smaller size
There is also a minimum position-size floor so the system does not continuously create tiny orders that are difficult to manage.
9. Exposure limits
Another distinction between a simple bot and a larger trading system is portfolio state.
It is not enough to know:
“I have a new signal.”
The system also needs to know:
“How much capital is already exposed?”
v3.2 tracks total open exposure and per-market exposure and blocks new positions once configured limits are reached.
For example:
Capital
↓
Open Position A
Open Position B
Open Position C
↓
Total Exposure
↓
Risk Check
↓
Allow / Reject New Trade
This prevents individual signals from being evaluated independently when they are actually part of the same portfolio.
10. Trading dashboard
The bot includes a dashboard for monitoring the trading system in real time.
The dashboard exposes:
- live or dry-run mode
- USDC and Polygon balances
- session PnL
- strategy state
- risk limits
- drawdown
- open exposure
- win/loss streak
- halted or paused state
It also includes controls such as:
- strategy toggles
- emergency stop
- panic sell
- live / dry-run switching
For automated trading, visibility is part of the system.
A bot that trades without an operator being able to understand its state is difficult to debug when something goes wrong.
11. Backtesting the execution layer
The repository also includes a JSONL order-book replay backtesting harness with fee and gas modeling.
Run:
npm run backtest
The purpose is not simply to ask:
“Would this strategy have made money?”
It is also useful for examining how execution logic behaves against recorded market conditions.
That makes it possible to test things such as:
- execution assumptions
- order-book conditions
- fees
- gas
- strategy behavior
- position sizing
A backtest that ignores execution costs can produce results that are very different from what happens in a live market.
12. Gas and operational protection
Trading logic can also fail because of infrastructure.
The bot monitors Polygon gas balance and can pause trading when the balance falls below the configured minimum.
There is also a wallet circuit breaker for copy trading.
After repeated failures, a wallet can be disabled for a cooldown period.
These controls are examples of a broader principle:
Operational failures are trading risks too.
The four strategies
The current bot includes four trading modes.
Arbitrage
Looks for opportunities where the combined YES and NO prices satisfy the configured arbitrage condition.
DipArb
Looks for rapid moves in short-duration BTC and ETH markets and attempts a hedged entry.
Smart Money
Filters selected Polymarket traders using performance and consistency requirements before copying trades.
Direct Trading
Provides manual execution tools including FOK orders and quick trading controls.
The complete strategy configuration is available in the repository.
Getting started
Clone the repository:
git clone https://github.com/casatrickdev/polymarket-trading-bot
cd Polymarket-trading-bot
Install dependencies:
npm install
Build the dashboard:
cd dashboard
npm install
npm run build
cd ..
Create your environment file from .env.example.
For initial testing, use:
DRY_RUN=true
Then start the bot:
npx tsx bot-with-dashboard.ts
The project documentation contains the full configuration and setup instructions.
Why I built it this way
There is a common tendency when building trading bots to spend most of the engineering effort on the strategy.
The strategy is the interesting part.
But once the system is actually running, many of the difficult problems move somewhere else:
- Did the order really fill?
- How much actually filled?
- Is the position state correct?
- Is the current market data fresh?
- How much capital is exposed?
- Did the transaction complete?
- Should the system continue trading after repeated failures?
These are infrastructure problems.
That is why this project is increasingly focused on the layer around the strategy:
Strategy
+
Execution
+
Risk
+
State
+
Monitoring
+
Recovery
For me, that is what makes a Polymarket trading bot an actual trading system rather than just a script that sends orders.
Open source
The complete project is available on GitHub:
https://github.com/casatrickdev/polymarket-trading-bot
The repository includes the bot, dashboard, configuration examples, documentation, and backtesting tooling.
Final thoughts
A Polymarket bot does not become reliable simply because its strategy works.
The system also needs to control execution, manage exposure, respond to failures, track actual fills, and know when it should stop trading.
That is the direction of v3.2:
less “just place the trade,” more “know exactly what is happening around the trade.”
⚠️ Trading involves risk. This software does not guarantee profits. Always test carefully and never trade more than you can afford to lose.
Top comments (0)