← Jordi Lluis / Projects

Polybow — Python trading bot

An independently operated Python system for live market-data capture and signed order execution on five-minute prediction markets—followed by a postmortem when the setup stopped finding durable opportunities.

01 / Problem

The real problem

Five-minute crypto markets compress the entire execution problem into seconds. Polybow had to identify the correct asset, time window and outcome token; compare the live price reference with the opening level; watch both outcome books; and submit an order before the quoted liquidity changed.

The candidate edge was not “predict whether Bitcoin goes up.” It was narrower: a very cheap ask could remain on the side that was close to resolving as the winner. The opportunity only existed if that ask was real, large enough and still present after detection, signing and submission.

Three records could tell different stories. A reference feed described direction, a WebSocket event described the visible book, and the CLOB account described orders and fills. An API acknowledgement was therefore not proof of execution, and a market name alone could not identify which bot branch placed an order.

02 / Iterations

Four versions, one evolving system

01

v1

Entry
Near expiry, often $0.96–$0.99
Engineering change
Entered the apparent winner late. Correct direction left little upside, while a reversal could lose almost the full ticket.

02

StratA

Entry
$0.40–$0.72 with 11–15 seconds remaining
Engineering change
Moved entry earlier and lower to improve payoff, accepting more time for the underlying market to reverse.

03

StratB

Entry
A wider timing window plus a larger gap from the opening reference
Engineering change
Made book updates event-driven, cached market metadata and warmed the signed HTTP/2 submission path.

04

UC

Entry
$0.01–$0.20 leftover asks
Engineering change
Targeted cheap residual liquidity with a maker order below the ask and, later, a taker leg when the quote remained available.

03 / Ownership

My contribution

I designed, built and operated the end-to-end path: market discovery, outcome-token mapping, reference-price handling, WebSocket book ingestion, decision logic, signed CLOB orders and the Ubuntu service running on AWS Lightsail.

I moved evaluation into the book callback, reduced the decision gate from 50 ms to 5 ms, cached market metadata, kept an HTTP/2 client warm and used coincurve signing to remove avoidable work from the submit path. Timing logs separated preparation from API response instead of treating either as fill latency.

I also built the evidence path around the bot: daily BBO and L2 JSONL recorders, rotation and compression, structured timing logs, a market-resolution ledger and parsers used for the postmortem. That made it possible to distinguish a visible quote, an order acknowledgement and later account activity.

This was an independent project. I owned the system design, implementation, deployment, operation and investigation.

04 / Architecture

How the system fits together

The live path moved left to right. Identity and reference data selected the contract; book events triggered a decision; the order client signed and submitted it; the evidence layer recorded what each stage actually knew.

01

Market identity

Reads from
Gamma market metadata + five-minute window
Produces
Asset, window, condition ID and outcome-token IDs.
02

Price reference

Reads from
Chainlink RTDS; Binance on some branches
Produces
Opening level, latest price and candidate direction.
03

Outcome books

Reads from
Polymarket WebSocket events
Produces
Best bids and asks for both outcome tokens.
04

Decision loop

Reads from
Identity + reference + book + timing and price guards
Produces
A prepared order candidate—or no action.
05

Order client

Reads from
Cached metadata + HTTP/2 + CLOB authentication + coincurve
Produces
A signed order request and named response timings.
06

Runtime

Reads from
Ubuntu on AWS Lightsail in Dublin
Produces
The bot process, restart path and daily recorder jobs.
07

Evidence layer

Reads from
Book events + timing logs + account and resolution records
Produces
A traceable postmortem instead of a success claim based on acknowledgements.

05 / Data model

How the data connects

The common join was market + five-minute window + outcome side. Each record answered a different question, so no single file was treated as the complete truth.

01

market / window / side

Reads from
Gamma identifiers and outcome-token mapping
Produces
The key connecting a quote, order attempt, account event and resolution.
02

ws_books_YYYYMMDD.jsonl

Reads from
Daily best-bid / best-ask WebSocket events
Produces
What price was visible and when it reached the recorder.
03

ws_books_l2_YYYYMMDD.jsonl

Reads from
Later depth snapshots
Produces
Whether cheap quoted liquidity had enough visible size to matter.
04

live.log

Reads from
Decision and submission instrumentation
Produces
Separate preparation and API-response timings for each attempt.
05

market_ledger.csv

Reads from
Public anonymized market-resolution rows
Produces
Reproducible outcome accounting for the historical case.
06

Public wallet activity

Reads from
Polymarket profile + Polygon transaction history
Produces
Externally visible account activity that can be inspected independently.

06 / Postmortem

Why the opportunity stopped working

UC depended on persistence: a low-priced ask had to remain in the winning-side book long enough to detect, sign and fill. On 28 April the venue moved to CLOB V2; on 2 May I also changed internal bot guards. Those changes overlapped, so the evidence cannot isolate one patch as the cause.

What the later data does establish is that the executable condition was no longer durable. A June–July scan covered 12,929 markets and 104.5 million best-book updates. It found one trigger, while apparent crosses disappeared within 0.02 seconds—too quickly for the earlier detect-and-submit path to rely on.

The defensible conclusion is that the residual-ask setup stopped appearing as a repeatable opportunity in the later books. Saying that one specific patch killed a proven edge would go beyond the evidence.

After live Polymarket trading stopped, I shifted the research workflow to capturing and replaying Hyperliquid public market data. That was a new data-research direction, not a claim that a second live bot was operated.

07 / Evidence

Inspect the real public activity

These links expose the account and historical ledger directly. They are evidence of activity and resolved outcomes; they are not presented as proof of durable profitability.