# Polymarket arbitrage trading bot: what the paper bot really does

> A C++ flagged repository that ships an npm based trading bot for five-minute Polymarket crypto markets, aimed at traders who want to watch a signal engine make decisions before risking real funds. The documentation is strong on strategy and weak on live execution.

**radioman/polymarket-arbitrage-trading-bot** — Polymarket arbitrage trading bot tool for BTC and ETH 5-minute prediction markets with automated execution, real-time analytics, and smart wallet copy trading. Polymarket trading bot  Polymarket trading bot  Polymarket trading bot  Polymarket arbitrage trading bot  Polymarket trading bot  Polymarket trading bot  Polymarket trading bot Polymarket 

- Repository: https://github.com/radioman/polymarket-arbitrage-trading-bot
- Stars: 538 · Forks: 139
- Language: C++
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/radioman-polymarket-arbitrage-trading-bot

## A signal engine for five-minute crypto prediction markets

The project describes itself as an advanced analytics and signal engine for prediction market trading on Polymarket, aimed at markets that resolve in five minutes on BTC and ETH price moves. That is a narrow target, and the whole design follows from it. A five-minute window is short enough that a human reading the order book cannot react in time, and long enough that a program can poll every few seconds and still have room to act.

The README lists the intended jobs as arbitrage detection, market inefficiency analysis, real-time trading signals, spread monitoring, execution optimization, and automated trading workflows. Feature claims follow the same shape: real-time arbitrage detection, smart trading signals, an analytics dashboard, AI-assisted trade optimization, position and PnL tracking, risk management tools, Telegram integration, and automated execution support.

Who this is for is fairly clear. It is for a solo retail trader who wants to test a hypothesis about BTC direction against Polymarket prices without wiring a live wallet on day one, and for a developer who wants to read a compact config file and a JSON state file rather than a full exchange client. It is not for a regulated desk, because the documentation describes a single-operator workflow with one virtual account and a Telegram channel, not an institutional order management stack.

One warning about the framing. The repository description repeats the phrase Polymarket trading bot seven times, the README opens with a referral link carrying a referral code, and it promotes a separate prediction market platform in its middle section. That tells you how the project is marketed. It also means the README is partly a sales page, so the configuration and the field names are the trustworthy part and the adjectives are not.

## Two terminals: a dashboard on port 3847 and a paper bot

The quick start asks for two processes. The first serves the dashboard:

```bash
npm start
```

After that command, opening http://localhost:3847 in a browser shows the analytics view. The README does not document a dependency installation step, so if the script fails to start you are on your own for the setup of the package tree; no npm install line appears anywhere in the guide.

The second terminal runs the bot against virtual money:

```bash
npm run demo
```

That command loads the active strategy and bankroll from config/demo-bot.json, writes its decisions to data/demo-bot/trades.log, and keeps its virtual balance, open positions, and trade history in data/demo-bot/state.json. A second file, config/demo-bot.example.json, is provided as a conservative starter template with lower risk defaults, and the README recommends it as the reset target. To wipe the virtual account and start over, delete data/demo-bot/state.json and restart the command, because stale positions are settled automatically on startup.

What a reader should see after those two commands is a dashboard that shows the bot's positions, and a log file that fills with the bot's reasoning, including HOLD lines that name the reason they did not trade. That last detail is the most useful part of the design for anyone learning the strategies, since the explanation for a skipped trade is written next to the trade it replaced.

## The strategy lives entirely in a JSON file you can override field by field

Everything the bot decides is expressed in config/demo-bot.json. The configuration shown in the README is a complete working example, and the mode key shows the default posture clearly:

```json
{
  "mode": "paper",
  "startingBalanceUsdc": 1000,
  "pollIntervalMs": 5000,
  "stateFile": "data/demo-bot/state.json",
  "logFile": "data/demo-bot/trades.log",
  "dashboard": {
    "enabled": true,
    "label": "Demo Bot",
    "address": "0x000000000000000000000000000000000000d30b",
    "color": "#22c55e"
  },
  "strategy": {
    "name": "btc_momentum",
    "side": "follow_btc",
    "betSizeUsdc": 25,
    "maxBetsPerWindow": 1,
    "minSecondsIntoWindow": 45,
    "maxSecondsIntoWindow": 270,
    "minBtcDeltaUsd": 20,
    "minFavoriteOddsPct": 72,
    "maxEntryOddsPct": 95,
    "takeProfitOddsPct": 100,
    "stopLossOddsPct": 0,
    "respectBtcOnOddsFallback": true
  }
}
```

The dashboard address in that file is 0x000000000000000000000000000000000000d30b, whose leading bytes are all zero, which is a hint that the shown values are demonstration settings rather than a wallet you should fund. The strategy block is the interesting part. maxBetsPerWindow caps entries inside a single five-minute window. minSecondsIntoWindow and maxSecondsIntoWindow define the 45 to 270 second band during which entries are allowed, so a bot configured with minSecondsIntoWindow at 200 will only look at the last 100 seconds of the window. minBtcDeltaUsdc of 20 means a BTC signal needs a 20 dollar move against the beat price, and maxEntryOddsPct of 95 rejects the most certain looking prices, which is unusual and worth understanding before you widen it.

The override mechanism matters more than any single value. Set strategy.name to one of the shipped presets and the bot loads the rest of that strategy's numbers from config/strategies/<name>.json, with your own value in demo-bot.json winning on any field you set. The README shows that partial override form:

```json
"strategy": {
  "name": "btc_or_odds",
  "betSizeUsdc": 15
}
```

So a reader can pick a preset, change the bet size to 15, and leave every other number at the preset default. Restart the command after editing, since the file is read when the bot starts rather than on every poll.

## Six strategies that disagree about what counts as a signal

The strategy table is the real content of this project, and it is a set of six mutually incompatible theories about the same five-minute market. btc_momentum is the default: it buys Up when BTC is at or above the beat plus a threshold, or when BTC is above the beat and the Up odds are at least the minimum, and it mirrors that on the Down side. odds_favorite ignores BTC entirely and follows whichever side Polymarket prices as favorite, using minFavoriteOddsPct. btc_and_odds requires BTC direction and the odds to agree, which is stricter than momentum. btc_or_odds accepts either condition, so it produces more entries than momentum. contrarian fades extremes, buying the cheap side when the favorite is very expensive, with its own minContrarianFavoritePct and maxUnderdogOddsPct thresholds. btc_mean_revert runs the opposite way, fading a Down that has already moved below the beat by the threshold.

The same file also controls which leg the bot may trade. A tradeLeg value of both, which is the default, allows either direction. Setting it to up makes Down signals resolve to HOLD, and setting it to down does the reverse, as the README shows:

```json
"strategy": {
  "name": "btc_and_odds",
  "tradeLeg": "down"
}
```

This is the part of the project with genuine engineering value, because it lets you hold two conflicting beliefs at once. Run btc_momentum in tradeLeg down and you are not betting on the bot being right about direction, you are asking whether the odds filter alone has been too generous. That is a cheap experiment in a paper account, and the presets directory makes it a one-line change rather than a code edit.

The trade-off is that the strategy names promise more than the configuration can deliver. mean reversion and momentum are stated in terms of BTC crossing the beat, but the beat price itself is not shown in the config, and the README does not explain how the beat is sourced. You can configure a rule without knowing exactly which price the rule compares against.

## Four reasons the bot holds when you want a trade

The README spends a section on a Down side that never trades, and the four causes it lists are the most honest part of the documentation, because they are the failure modes you will actually hit.

The first is a leftover open position. When an Up position is still live, the bot reports HOLD with the reason holding_position and shows the open position, and restarting after a fix or deleting data/demo-bot/state.json clears it. The second is a distance problem. A BTC price nine dollars below the beat fails a minBtcDeltaUsd of 15, so the fix is to lower the threshold to 10 or to set btcSignOnly to true and require only that BTC sits below the beat. The third is a price ceiling: Down odds of 96 percent against a maxEntryOddsPct of 88 produce the reason odds_too_high. The fourth is timing, where an entry window that starts too late leaves no usable part of the five-minute round.

The pattern across all four is that a single strategy object contains several independent filters, and the bot reports a reason code when a filter rejects an entry. That is a real strength for anyone trying to learn why a strategy underperforms, and it is also the reason the configuration is fiddly. Because the filters interact, widening maxEntryOddsPct while a stale position is open changes nothing, and lowering minBtcDeltaUsd while tradeLeg is set to up still produces no Down entry. The README treats these as a checklist of common causes rather than a single model of the decision, so expect to bisect by hand.

## The repository contents do not match the README workflow

Two repository facts sit awkwardly next to the guide. The primary language recorded for the project is C++, and the top-level entries are .gitignore, LICENSE, README.md, WebRtc.NET.Demo/, WebRtc.NET.sln, WebRtc.NET/, WebRtcNative/, packages/, and web/. Those names describe a WebRTC binding, not a Node trading bot, and the quick start is entirely npm based with no build step for a C++ library. Nothing in the README explains the connection, and there is no documentation of a shared library, an include path, or a build command.

The other structural detail is the branch and the release history. The default branch is staging, which is the branch a maintainer would use for work in progress rather than a settled release, and the repository has no GitHub releases at all. There is therefore no changelog to consult, no tag to pin, and no upgrade path written down. Combined with the fact that the license is recorded as Other, a custom licence GitHub cannot classify and that lives in the LICENSE file, any adoption decision has to start by reading that file, since the SPDX identifier in the repository metadata does not tell you what you are allowed to do.

Maintenance status follows from one date: the last push was on 2026-06-19. The repository is not archived. Nothing in the README claims a schedule of releases, and there are no releases to support one.

## Paper mode is the only mode the documentation shows

The single largest gap for a trading tool is that every documented configuration is simulated. The mode key in the sample config is set to paper, the state file is described as holding a virtual balance, and the reset instructions talk about resetting a virtual account. The README mentions automated execution support, wallet copy trading in the repository description, and a Telegram integration, but it gives no key-management steps, no live order placement example, and no explanation of how a real wallet address and private credentials are supplied. The dashboard address in the sample file is a zero-prefixed value, which suggests the live path exists but is not written down here.

The same silence applies to failure handling. The README does not document rollback, does not explain how the bot reconciles a real order against the paper state file, and does not say what happens if the process is killed mid-window. It also does not document a dependency install step, so a first run on a clean machine depends on the reader filling that gap.

The result is a project that is easy to evaluate as a signal engine and hard to evaluate as an execution system. The honest reading is that this is a research and monitoring tool with a live mode that the documentation does not cover, so the correct first use is the paper account, and the correct time to judge it is after enough five-minute windows have elapsed for the trade log to contain a meaningful number of decisions.

## Conclusion

Adopt this project if you want a signal engine and position tracker for five-minute crypto prediction markets and are willing to work in paper mode first, because the documented workflow never leaves the simulator. Stay away if you need a documented live-execution path, a release trail, or a paperless deployment, since the repository ships no GitHub releases and the only configuration shown sets mode to paper. Before committing anything, check the strategy name and trade leg you select against the six presets in config/strategies, and confirm that the dashboard and the bot agree on the state file under data/demo-bot.

## FAQ

### How do I start the polymarket arbitrage trading bot in paper mode?

Run npm start in one terminal for the dashboard and open http://localhost:3847, then run npm run demo in a second terminal, which loads the strategy and bankroll from config/demo-bot.json and writes to data/demo-bot/state.json and data/demo-bot/trades.log.

### Why is the polymarket arbitrage trading bot not placing a Down trade?

The README lists four causes: an old Up position still open, which shows as HOLD (holding_position), BTC not far enough below the beat for minBtcDeltaUsd, Down odds above maxEntryOddsPct, which reports odds_too_high, or an entry window that starts too late.

### How do I change the trading strategy used by the polymarket arbitrage trading bot?

Set strategy.name in config/demo-bot.json and restart npm run demo, since the remaining numbers load from config/strategies/<name>.json. Any field you add to demo-bot.json overrides the preset value for that field.

### Does the polymarket arbitrage trading bot trade real money out of the box?

Every configuration in the documentation sets mode to paper, with a virtual balance, a state file, and a reset procedure for a virtual account. The README mentions automated execution and wallet copy trading but does not document the steps for connecting a real wallet, and the dashboard address in the sample config is a zero-prefixed value.

## Sources

- [Issues](https://github.com/radioman/polymarket-arbitrage-trading-bot/issues)
- [radioman/polymarket-arbitrage-trading-bot on GitHub](https://github.com/radioman/polymarket-arbitrage-trading-bot)
- [README](https://github.com/radioman/polymarket-arbitrage-trading-bot/blob/staging/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/radioman-polymarket-arbitrage-trading-bot
