LESSON 36

Execution Confirmation: Don't Trust the Log

Your system logged 'Trade placed.' The dashboard shows a position. But the order never filled. You are managing a phantom — a record of something that never happened.

10 min read·Discipline

Your trading system logs a clean entry: "Trade placed: BUY ETH at 0.65." The database records the position. The dashboard renders it with a green indicator. You see the position and move on to the next signal.

But the order never filled. It sat in the order book as a limit order, waiting for a counterparty that never arrived. The price moved. The order expired. Your system shows a position that does not exist. Your P&L calculations include profit from a trade that never happened.

You are managing a phantom. A record of something that never occurred, indistinguishable from a record of something that did.

WARNING

The most dangerous state in any automated system is a recorded action that did not actually execute. It is invisible, persistent, and compounds silently — every subsequent decision built on that phantom is also wrong.

Three-Layer Confirmation Model

The Phantom Position Problem

The mechanics are deceptively simple. Your system calls an API to place an order. The API returns a success response — 200 OK, order ID assigned, status: open. Your system logs "order placed" and records the position.

But open does not mean filled. It means the order exists in the book. It is waiting. It may fill in a millisecond. It may never fill. The API told you "I accepted your order." It did not tell you "your order executed."

The gap between accepted and executed is where phantom positions are born.

This is not a trading-specific problem. It is a confirmation gap — the space between calling an API and verifying that the API actually did what you think it did. Every automated system that acts on external services has this gap. Trading just makes the cost visible in dollars.

You must have a rising standard of performance. A ship that has not been in a collision is not necessarily well run. The question is: does the crew know what actually happened, or do they only know what the instruments say happened?

Admiral Hyman Rickover · Congressional Testimony, 1982

The Three-Layer Confirmation Model

One confirmation is not enough. The system needs three, each verifying a different aspect of execution.

Three-Layer Confirmation Model — Pipeline and Verification Layers

Layer 1 — API response status. The response must confirm execution, not acceptance. status: "matched" or status: "filled" is confirmation. status: "open" or status: "pending" is not. This layer catches the most common phantom: the order that was accepted but never matched.

Layer 2 — Explicit size matched. Even with a matched status, verify size_matched > 0. An order can technically match at zero quantity due to edge cases in order book mechanics. The number must be positive. This is the quantitative proof that something actually changed hands.

Layer 3 — Position tracked with recovery identifiers. The confirmed position must be stored with enough metadata to survive a process restart. If your trading bot crashes and restarts, it needs to know what positions exist. That requires durable identifiers — condition_id, token_id, order ID — stored in persistent storage, not in memory. A position that exists only in a running process is one crash away from being a phantom.

Confirmation Layers
3
all must pass before logging 'filled'
Phantom Detection
size_matched
the single field that separates real from ghost
Recovery Requirement
Durable IDs
position must survive process restart

The Library Name Trap

create_order() sounds like it creates a filled order. It does not. It places a limit order in the book. That order may or may not fill.

MarketOrderArgs sounds like a market order. But whether it fills immediately depends on the order_type parameter. FOK (fill-or-kill) fills immediately or cancels. GTC (good-till-cancelled) sits in the book until matched or expired.

Function names are marketing copy from library authors. They describe intent, not behavior. The function name tells you what the developer hoped would happen. The return value tells you what actually did.

This trap extends beyond trading libraries:

  • send_email() places the email in a queue. It does not confirm delivery.
  • deploy() triggers a pipeline. It does not confirm the new version is serving traffic.
  • charge_customer() initiates a payment. It does not confirm settlement.
  • create_resource() submits a creation request. The resource may take minutes to provision.

In every case, the function name implies a completed action. The actual behavior is an initiated process with a completion state that must be checked separately.

INSIGHT

Read the return value, not the function name. The return value is the only truth your code receives from the external system.

If the return value does not contain explicit confirmation of the action you expected, the action has not been confirmed. Period.

Beyond Trading: The Universal Pattern

The confirmation gap appears everywhere automated systems interact with external services. The domain changes. The pattern does not.

Email delivery. sent means the email left your server. delivered means the recipient's server accepted it. read means the recipient opened it. Logging "email sent" when you mean "email queued" creates phantom notifications — users who you believe were notified but never received the message.

Deploy pipelines. pushed means the code reached the remote. deployed means the CI pipeline succeeded. serving means the new version is handling live traffic. A deploy pipeline that logs success after git push but before the deployment completes will show "deployed" while the old version is still serving.

Payment processing. charged means the payment was initiated. settled means the funds transferred. in your account means the settlement cleared. A system that records revenue at the charged stage will overcount — some charges will fail, reverse, or dispute.

Async APIs. The most insidious pattern. The API returns 200 OK immediately — because it accepted the request. The actual processing happens asynchronously. The 200 confirms receipt, not completion. Systems that treat 200 as "done" will log completed actions that are still in a queue, possibly failing silently.

DOCTRINE

The rule is absolute: never log a result until you have confirmation from the system that actually performed the action.

"I called the API" is not confirmation. "The API confirmed the result" is confirmation. The difference between these two statements is the difference between a real position and a phantom.

The Dashboard Artifact

Here is how phantom positions surface. Your dashboard shows a trade with a score field displaying "–" instead of a number. That dash is not a UI bug. It is evidence.

The signal was generated. The order was placed. But the fill confirmation never came. The score — which depends on the fill price — was never calculated because there was no fill price. The system stored a default value. The dashboard rendered the default. The dash is the ghost in the machine.

Every dashboard field that shows a default, null, or placeholder value is a potential confirmation gap. It means the system wrote a record before confirmation completed, and the confirmation data never arrived. The record exists. The action does not.

Train yourself to see these artifacts. A blank field in a dashboard is not missing data. It is evidence of a confirmation gap in the pipeline that produced the record.

Lesson 36 Drill

Audit one automated system you operate. Trace the path from action initiation to confirmed completion.

For each external API call that produces a logged result:

  1. What does the API actually confirm in its response? ("Accepted" vs. "completed")
  2. Is your system logging the result at the right stage — after confirmation, not after the call?
  3. What happens if the action is initiated but never completes? Does your system detect the phantom?
  4. Can the system recover its state after a crash? Does it know which actions were confirmed vs. merely initiated?

If any answer is "I don't know" or "we log at the call stage," you have phantom records in your system right now. The drill is to find them before they find you.

Bottom Line

The log says it happened. The dashboard shows it happened. The database records that it happened. None of these prove it actually happened. They prove your system believes it happened.

Belief is not confirmation. Confirmation is an explicit signal from the external system that the action completed — with a positive quantity, a filled status, and enough metadata to survive a restart.

Build systems that confirm before they record. The alternative is an infrastructure of phantoms — records that look real, dashboards that look accurate, and decisions built on events that never occurred.

Explore the Invictus Labs Ecosystem