All Articles

Execution records

An order intent is not a completed trade

Follow one order through intent, submission, fill and reconciliation, and read what is still outstanding without guessing.

A trader at his laptop checking his phone while he waits for a confirmation.
Accepted is not filled.

A Submission Is Not An Outcome

Most trading interfaces collapse the moment of ordering into one gesture. You press a button, a spinner turns, and a row appears. The row implies that something happened. What actually happened is at least four separate things, and any one of them can be the last thing that happens.

This matters most in the case nobody designs for: the request leaves, and the answer does not come back. The connection drops, the venue returns a code that means try again rather than no, or the process restarts between one step and the next. At that moment the only honest statement about the account is that its state is unknown. Software that treats an unknown as a nothing will submit again. Submitting again is how one intended position becomes two real ones.

CVEST records the order lifecycle as four states, and the rule that connects them is short: persist intent before submission, and reconcile uncertainty before any retry. This article follows one order through those states, using what the execution service actually does.

Four States, Not One Event

An order in the defined-risk options loop belongs to one leg of one cycle, and it carries a status and a submission state that answer different questions. The status is about the venue: pending, filled, canceled or rejected. The submission state is about the request itself: intent, acknowledged, or submission unknown.

The pair is deliberate. An order can be acknowledged and still unfilled, which is ordinary. An order can be an intent and never acknowledged, which means the venue may or may not have seen it. Reading only one of the two fields produces a confident answer to a question you did not ask.

The execution tick runs every five seconds, in-process. Each tick either advances the cycle or refuses to, and refusing is a normal outcome rather than a failure to be retried past.

An acknowledgement is not a completed trade1Intent recordedPersisted before anythingreaches the venue.2SubmittedSent to the account.Acceptance is not a fill.3Fill, partial or noneThe venue decides.A partial fill is normal.4ReconciledUncertainty is resolvedbefore any retry.
An order can stop at any stage until reconciled.

Why The Intent Is Written First

Before a live order is sent, the executor builds the order record, gives it an identifier of its own, marks its submission state as intent, and attaches a decision-context record describing the cycle, the leg and the phase. It then writes that record to the database inside a transaction, together with the capital the cycle reserves. Only after the transaction commits does anything reach the venue.

The row it writes is an order intent, and it holds the exact request that will be sent: the instrument, the margin mode, the client order identifier, the side, the order type, the size and the limit price. The insert does nothing on conflict, and if a record with the same identifier exists with a different cycle or a different request body, the write fails with the message that an immutable order intent cannot be changed or reused. There is no path that edits an intent after the fact.

The reason for the ordering is recoverability. If the process dies immediately after the venue accepts the order, the durable record of what was attempted already exists, written before the attempt. A record written after a successful response would be missing in exactly the case where it is needed.

The capital reservation carries the same honesty. While an order is pending and not yet acknowledged, the cycle’s reservation is marked uncertain. Capital tied to an order whose outcome is unknown is not free capital, and it is not reported as free capital.

The Three Answers A Venue Can Give

Submission produces one of three results, and the executor treats them differently. If the venue returns its own order identifier, the order is marked acknowledged and the identifier is stored beside the intent. Acknowledgement means the venue has the order. It says nothing about fills.

If the venue returns a definite rejection, the order is marked rejected and the cycle moves to closing, with a reason recorded. For an entry the reason says the exchange rejected the entry. For an exit it says the exchange rejected the exit and that the owned contracts remain open, which is the more consequential of the two and is written down as such.

The third result is the one that decides whether the design is serious. A small set of venue codes, a missing response and a response without an order identifier are all classified as ambiguous rather than negative. In that case the order is marked submission unknown, the record is saved, and the error is raised so the tick ends. Nothing is resubmitted. The next tick finds an outstanding order and goes to reconciliation instead of to a new order.

Double Submission, In Plain Words

Idempotency has a plain meaning here: doing the same thing twice must not produce two positions. Two mechanisms carry that weight, and neither of them is a retry counter.

The first is naming. The identifier CVEST generates for the order is sent to the venue as the client order identifier, so the venue knows the order by the same name the journal does. That name is what makes an unknown outcome answerable. Reconciliation asks the venue about that exact identifier, matches the instrument, the side and the venue’s own order identifier against the stored intent, and refuses to accept a record whose identity does not line up.

The second is refusal. A new order cannot be created while any order on the cycle is still pending; the attempt fails with a message saying an outstanding order requires reconciliation before another intent. Settlement is blocked by the same condition. When a reconciliation attempt cannot complete, the error text is explicit that no order was resubmitted, because that is the fact a reader most needs at that moment.

The safe response to an unknown outcome is to ask the venue by name, not to send the order again.

Reconciliation also refuses to move backwards. Cumulative filled quantity may not decrease or exceed the ordered quantity, the fee currency must be the expected one, and the individual fills must sum to the cumulative quantity, sum to the reported fee, and produce the reported average price. If the venue’s own records do not yet agree with each other, the order stays pending and the tick ends with a message about waiting for complete fill history. The venue response and the fill records are stored on the order as evidence.

Partial Fills And The Order Of The Legs

Orders in the options loop are sent as immediate-or-cancel limit orders. They do not rest in the book. Whatever is available at the limit fills at once, and the remainder is canceled by the venue. A partial fill therefore arrives as a terminal order with a filled quantity smaller than the quantity that was asked for, not as a working order you could wait on.

When that happens during entry, the cycle stops building and moves to closing, with the reason recorded as a partial fill or rejection on entry. The loop does not top up the missing contracts at a worse price. It unwinds what it has.

Leg order is a safety property, not a preference. During entry, protective buys are sorted ahead of short sells, and every short order is checked against the protective contracts already confirmed filled; a short that would exceed that protection is refused. During an exit the sort is reversed, shorts first, and an attempt to close a protective leg while any short leg still has exposure is refused outright. Exits are attempted with limit orders, so quotes can move and liquidity can disappear between one tick and the next.

Paper and replay modes fill at the limit immediately and record a synthetic fill, which is the point: they show the shape of the workflow, not the fill a real book would have given. An interrupted simulation order is marked canceled on recovery and the cycle is closed out, because there is no venue to ask.

Reading What Is Still Outstanding

Each cycle in Position history lists its orders individually: side, quantity, instrument and strike, whether it was an entry or an exit, the order identifier, the filled quantity over the quantity ordered, the average price and the status. Remaining exposure on a leg is the sum of its entry fills minus its exit fills, which is why the per-order lines are shown rather than a single net figure.

The table below is a reading aid for those lines. It is not a score and not a health indicator. Read across from the state you are looking at to the column that says what it does not establish, because that column is where mistaken conclusions are usually made.

State on the recordWhat it establishesWhat it does not establish
Intent, not yet acknowledgedThe exact request was persisted, under an identifier the venue also usesThat anything reached the venue at all
Acknowledged, still pendingThe venue returned its own identifier for that requestThat any contract has changed hands
Submission unknownThe attempt happened and the outcome is not yet evidenceThat nothing filled; only reconciliation settles that
Terminal, filled below quantityThe fills the venue proved, with their fees and average priceThat the missing quantity is still working somewhere
Reconciled and terminalFills, average price and fees agreed against venue recordsWhat the position is worth at this moment

Account, venue and live-or-paper identity stay attached to every one of those records, and reconciliation re-checks them: if the account bound to a cycle is no longer the account observed, the executor stops and says so rather than acting on the wrong book.

First Steps

  1. Open the cycle in Position history and read each order line on its own — filled over quantity, average price, status — before reading any total for the cycle.
  2. If any order is not terminal, stop there and download that cycle’s decision context as JSONL; the order intent and the reconciliation records are in it, with the venue evidence attached.
  3. Take the order identifier printed on the line and look up that same identifier at the venue, in the account named on the record, before drawing any conclusion about the position.

What The Record Will Not Do For You

Automated live execution is paused. The live-execution flag defaults to off, and with it off the executor refuses to place an order and says that existing positions remain monitored. What you can inspect today is the record and its structure, in paper and replay, and any history a live account has already produced.

The options loop has no cancel and no amend, and this is a consequence of the order type rather than a gap: an immediate-or-cancel order leaves nothing resting to cancel. The separate IBKR ticket path does submit day limit orders, and there a cancel is available on an order that is still working at the broker and owned by CVEST. That path also blocks a second submission from the same preview outright, and when a broker warning expires it says plainly that the original order must be reconciled and no replacement should be sent.

None of this makes an execution outcome predictable. It makes the outcome legible: at any moment you can say what was intended, what was sent, what the venue confirmed, and what is still unresolved. When the honest answer is that something is unresolved, the system is built to keep saying so rather than to produce a tidier one.

Read the risk information and check the current product scope before evaluating a workflow.

Sign up