Sitemap
Casatrick - Web3 Trading Systems

Casatrick - Web3 Trading Systems

Web3 Full-Stack Developer building Polymarket trading bots, automated trading infrastructure and scalable trading-system backends. https://t.me/casatrick

Press enter or click to view image in full size
polymarket trading bot execution analytics

Polymarket Trading Bot Execution Analytics: Turning Execution Events Into Operational Signals

8 min readOct 3, 2026

--

A Polymarket trading bot can be running, placing orders, and making money while the execution layer is quietly getting worse.

Latency can increase.

Partial fills can become more common.

Orders can be rejected more frequently.

Executions can remain unresolved for longer.

Position mismatches can start appearing.

Recovery can take longer than it used to.

None of those problems necessarily show up in the P&L immediately.

That is why I’m interested in execution analytics as a separate part of the trading system.

The goal isn’t to build a dashboard with dozens of numbers.

The goal is to turn execution events into information that answers:

What is the execution layer doing right now, and does the system need to react?

Start with the execution lifecycle

The metrics become much easier to reason about when the execution lifecycle is explicit.

A simplified lifecycle is:

Order Created
↓
Order Submitted
↓
Fill Observed
↓
Transaction Pending
↓
Transaction Confirmed
↓
Settled
↓
Position Verified

Around that lifecycle, the system can also enter states such as:

Rejected
Cancelled
Failed
Retrying
Unknown
Inconsistent

Each transition is an observation.

Those observations can then become the raw material for analytics.

Metrics should come from events

Instead of scattering counters throughout the code, I prefer to make important state transitions observable.

For example:

ORDER_SUBMITTED
FILL_OBSERVED
TX_PENDING
TX_CONFIRMED
SETTLEMENT_OBSERVED
POSITION_VERIFIED
POSITION_MISMATCH
RECOVERY_STARTED
RECOVERY_COMPLETED

An event can contain information such as:

execution_id
order_id
trade_id
market_id
event_type
event_timestamp
observed_timestamp
quantity
execution_state
reason

Then useful metrics can be derived from those events.

For example:

ORDER_SUBMITTED
↓
FILL_OBSERVED
= Fill Latency

Or:

RECOVERY_STARTED
↓
RECOVERY_COMPLETED
= Recovery Duration

This creates a single event model that can support logs, metrics, incident analysis, and dashboards.

Order latency

One of the first things I would measure is the time between the trading decision and order submission.

Conceptually:

Strategy Decision
↓
Order Created
↓
Order Submitted

That can produce:

decision → order creation
order creation → submission

I don’t want to look only at an average.

A distribution is more useful:

p50
p95
p99

A system with a stable median but a growing tail has a different operational problem from one with uniformly increasing latency.

The important question is not:

“Is the average okay?”

It is:

“Is the execution path behaving differently from its normal operating range?”

Fill latency

After submission, measure the time until a fill is observed:

Order Submitted
↓
Fill Observed

For example:

Order A → 140 ms
Order B → 180 ms
Order C → 3.4 s

One slow execution isn’t necessarily a problem.

A sustained change is more interesting.

That’s why execution analytics should preserve enough context to compare:

market
side
strategy
order type
time window

A single aggregate fill-latency number doesn’t tell you much.

A time series segmented by market or execution type can.

Fill ratio

Suppose the strategy requests:

100

and execution produces:

75

Then:

fill ratio = 75 / 100

The point of tracking this isn’t to create a universal “good” percentage.

It is to observe how execution behaves over time.

For example:

Previous period:  88%
Current period: 67%

That change deserves investigation.

And it becomes much more useful when paired with:

partial-fill rate
order latency
market
strategy

The metric gives you a signal.

The surrounding data helps explain it.

Partial-fill rate

Fill ratio tells you how much of each request was executed.

Partial-fill rate tells you how often an order is only partially executed.

Those are different.

For example:

100 orders
27 partially filled

gives:

partial-fill rate = 27%

But the operational question is what happens next.

A partial fill can create:

remaining quantity
↓
position update
↓
exposure update
↓
risk check
↓
possible reconciliation

That is why execution analytics needs to be connected to the rest of the trading system.

The metric isn’t useful only for reporting.

It can tell you whether downstream state handling is becoming more active.

Rejection rate

Another useful metric is the proportion of submitted orders that are rejected.

Conceptually:

rejected orders
----------------
submitted orders

The important part is not assigning a universal acceptable number.

Watch the trend.

For example:

Monday     0.7%
Tuesday 0.8%
Wednesday 0.9%
Thursday 3.6%

A change like that is worth investigating.

The next step is to break the rejections down by reason where the underlying data allows it.

Otherwise a single rejection counter can hide several different problems.

Execution failures need categories

A single metric called:

execution_failures

is often too broad.

I would rather separate failures into areas such as:

ORDER_SUBMISSION_FAILURE
FILL_PROCESSING_FAILURE
TRANSACTION_VERIFICATION_FAILURE
POSITION_RECONCILIATION_FAILURE
RECOVERY_FAILURE

Now analytics can tell you where the system is actually struggling.

For example:

Order submission:
normal
Transaction verification:
degrading
Recovery:
normal

That’s very different from:

Order submission:
degrading

The first points toward verification.

The second points toward the execution path itself.

Unknown execution states

This is one of the more useful operational measurements.

A trading system will sometimes have incomplete information.

For example:

FILLED
↓
TX_PENDING

or:

Execution = UNKNOWN

I would measure both:

number of unknown executions

and:

time spent unresolved

For example:

Unknown executions: 3
Oldest unresolved: 18.2 seconds

That tells you much more than:

Unknown: 3

The same state may be harmless for 200 ms and operationally significant after several seconds.

This is closely connected to the Polymarket Execution Verifier I’ve been building.

Position mismatch is an execution-health signal

Execution doesn’t stop at the fill.

Eventually the system needs to know whether its resulting position matches the account.

For example:

Expected: 100
Observed: 40

Now there is a mismatch.

This is the same problem I wrote about in Polymarket Position Reconciliation.

For analytics, track:

mismatch count
mismatch duration
largest difference
markets affected
time to resolution

This starts to answer a more interesting question:

How often does the trading system disagree with external state, and how quickly does it recover?

That is much closer to system health than simply watching P&L.

Reconciliation frequency

Reconciliation itself is worth measuring.

Get Casatrick - Web3 Trading Systems’s stories in your inbox

Join Medium for free to get updates from this writer.

Not every reconciliation means something is broken.

Some are expected:

application restart
WebSocket reconnect
scheduled state check

Others may come from actual problems:

state mismatch
unexpected API response
execution uncertainty

So distinguish the trigger.

For example:

Reconciliation
├─ restart
├─ reconnect
├─ mismatch
└─ manual

Then measure:

frequency
duration
result
trigger

If reconciliation begins happening much more often, that can be a useful indication that another component needs attention.

Recovery duration

A recovery incident can be represented as:

DISCONNECT
↓
PAUSE
↓
RECONNECT
↓
RECONCILE
↓
VERIFY
↓
RISK CHECK
↓
RESUME

That gives you a natural metric:

RECOVERY_COMPLETED - RECOVERY_STARTED

But the total duration isn’t enough.

Break it into stages:

disconnect → reconnect
reconnect → reconciliation
reconciliation → verification
verification → risk check
risk check → resume

Now a slow recovery can be investigated.

This connects directly with the Polymarket WebSocket recovery work in the broader trading-system cluster.

Metrics need context

An execution metric without context can be misleading.

Suppose:

Fill Ratio = 72%

That doesn’t tell you much on its own.

Compare:

Market A → 72%
Market B → 41%

or:

Strategy A → 91%
Strategy B → 55%

or:

Normal → 84%
Current → 72%

The useful dimensions depend on your system, but I’d generally keep:

market
strategy
side
order type
time
system state

available for filtering.

This makes the same metric useful for both engineering and operations.

Store the event, derive the metric

I prefer retaining the events and calculating metrics from them.

For example:

10:41:08.120  ORDER_SUBMITTED
10:41:08.340 FILL_OBSERVED
10:41:08.342 TX_PENDING
10:41:08.910 TX_CONFIRMED
10:41:09.020 POSITION_UPDATED
10:41:09.040 POSITION_VERIFIED

From this, you can derive:

fill latency       = 220 ms
fill → confirmation = 570 ms
confirmation → position verified = 130 ms
total = 920 ms

If the metric changes later, you still have the observations needed to investigate why.

That is preferable to storing only:

average fill latency = 240 ms

and throwing away the underlying evidence.

Analytics should also help reconstruct incidents

The event history can be useful when something goes wrong.

For example:

ORDER_SUBMITTED
↓
FILL_OBSERVED
↓
WEBSOCKET_DISCONNECTED
↓
PROCESS_RESTARTED
↓
POSITION_MISMATCH
↓
RECONCILIATION
↓
POSITION_VERIFIED

Now the analytics layer can become part of incident investigation.

This connects naturally to the Polymarket Trading Bot Incident Recovery work.

The metric tells you something changed.

The event history helps explain what changed.

From metrics to system health

This is where execution analytics becomes more interesting.

Suppose:

fill latency ↑
rejection rate ↑
unknown execution duration ↑

The system can derive:

Execution Health = DEGRADED

Or:

position mismatch count ↑
reconciliation duration ↑

can produce:

State Health = DEGRADED

The metrics become inputs to the control layer.

Conceptually:

Events
↓
Metrics
↓
Health
↓
Risk
↓
Control

That’s the connection I care about.

Analytics should be able to change behavior

A dashboard that nobody acts on isn’t much of a control system.

For example:

Anomaly Detected
↓
Investigate
↓
Pause / Adjust
↓
Recover
↓
Healthy

The actual thresholds should be configurable.

You might decide that:

unknown execution > threshold

blocks new trading.

Or:

market-data age > threshold

pauses a strategy.

Or:

recovery duration > threshold

raises an alert.

The point isn’t to hardcode these decisions into analytics.

The point is to provide reliable information to the system that makes the decision.

Simple thresholds are enough to start

I wouldn’t begin with machine learning.

Start with deterministic rules.

For example:

p95 latency > configured threshold

or:

unknown executions > configured threshold

or:

recovery duration > configured threshold

or:

position mismatches > configured threshold

Then:

Normal
↓
Threshold Crossed
↓
DEGRADED
↓
Investigate

This is explainable.

It is testable.

And it is much easier to operate than an opaque anomaly model.

What a useful execution-health view looks like

I would want the operator to see something like:

EXECUTION HEALTH
Orders                1,248
Fill Ratio 86%
Partial Fills 94
Rejections 11
Unknown Executions 3
p50 Fill Latency 180 ms
p95 Fill Latency 620 ms
Position Mismatches 2
Active Recoveries 0

The exact dashboard isn’t the point.

The important thing is that every number can be traced back to actual system events.

Analytics should fit the control plane

The architecture I’m moving toward looks like:

Polymarket
↓
Trading Bot
↓
Execution Events
↓
Execution Verifier
↓
Position Reconciliation
↓
Risk Controls
↓
Control Plane
↓
Execution Analytics

And analytics should also observe the system itself:

Execution Analytics
|
+---- Latency
+---- Fills
+---- Rejections
+---- Unknown State
+---- Mismatches
+---- Reconciliation
+---- Recovery

Those signals can then flow back into:

Health
Risk
Control

So the architecture becomes a loop rather than a reporting endpoint.

The metrics I would start with

I don’t think you need fifty metrics at first.

I’d start with:

1. Order latency
2. Fill latency
3. Fill ratio
4. Partial-fill rate
5. Rejection rate
6. Execution failure count
7. Unknown execution count
8. Unknown execution duration
9. Position mismatch count
10. Reconciliation duration
11. Recovery duration

Then add another metric when there is a real question it can answer.

That keeps the analytics layer useful instead of noisy.

Why this matters for an automated trading system

A bot can be profitable while the execution system is becoming less reliable.

For example:

P&L       → healthy
Latency → worsening
Fills → worsening
Unknowns → increasing
Recovery → slower

The P&L hasn’t necessarily told you that the infrastructure is deteriorating.

Execution analytics can.

That’s why I see analytics as a separate layer around automated trading:

Execute
↓
Observe
↓
Measure
↓
Detect
↓
React

The objective isn’t a prettier dashboard.

It is a trading system that can see its own operating condition.

Final takeaway

The question isn’t only:

“Did the bot make money?”

It is also:

“How is the execution system behaving?”

I want to be able to see:

latency
fills
partial fills
rejections
execution uncertainty
position mismatches
reconciliation
recovery

and connect those observations to actual system behavior.

The model is:

Execution
↓
Events
↓
Metrics
↓
Health
↓
Risk / Control
↓
Action

That is the direction I’m taking with the Polymarket trading infrastructure I’m building.

A trading system should not only execute.

It should be able to tell you when execution is changing, when state is becoming unreliable, and when the system needs to stop and investigate before continuing.

--

--

Casatrick - Web3 Trading Systems
Casatrick - Web3 Trading Systems