vike
Tools

cancel_order

Cancel one resting order by client order id on a running vike-tradehub node — previewed by default, sent only on a second call carrying both confirm and the preview_token.

cancel_order withdraws exactly one resting order, named by its client order id. It is a write tool, so it is annotated destructiveHint: true and previews unless a call carries both confirm: true and the preview_token its own preview returned, and it needs vike-cli mcp --node <host:port> plus VIKE_TRADEHUB_CONTROL_KEY.

Arguments

ParameterTypeRequiredNotes
client_order_idstringyesThe id to cancel
reasonstringnoRationale for the node's audit trail
confirmbooleannoMust be the JSON boolean true and be accompanied by preview_token — either one missing returns a preview
preview_tokenstringnoThe token this tool's preview returned. Fires once, expires after 60s, bound to the command it previewed

Omitting the id is a tool error from verbs::verb_from_tool_args before any command is built.

The preview

Call it without confirm and you get preview_of(...): will_execute: false, the resolved wire_command, the advisory guardrail, the node's own dry-run when there is a node to ask, the echoed reason, the confirm note, and a preview_token. Nothing is sent. With no node configured nothing is opened either.

To execute, call again with the same arguments plus both confirm: true and that token. Either one on its own returns another preview — not an error — so read will_execute rather than assuming the second call landed. The token fires once, expires after 60 seconds and is bound to this exact cancel; Live node has the four rules and the argument for why it is not a secret.

The guardrail on this verb is always Guardrail::NoSize — rendered as within_limits: true with a note saying there was no order size to check. That is not a pass; it is the honest answer that a cancel has nothing to size.

The rationale round-trip is pinned by a_write_preview_echoes_the_reason_without_changing_the_command, which uses this tool: a reason of " stale quote after the feed gap " comes back trimmed, a blank one comes back null, and the wire_command is byte-identical with and without it. The reason rides beside the command on the wire and can never alter it.

What the node does with it

lower_command maps WireCommand::Cancel straight to the core's OrderIntent::Cancel, and this is one of the order-scoped verbs, so the acknowledgement echoes the client_order_id you named rather than an empty string.

ControlLimits::vet consumes a rate token, as it does for every command, and then stops: its doc is explicit that the notional cap applies only to order-increasing verbs carrying a price, and that cancel, flatten, mass-cancel, market-exit and trading-state are risk-reducing and never size-capped. Cancelling is never refused for being too large.

Accepted means the node took the command, not that an order went away

A cancel is fire-and-forget, and the code says so plainly: verbs::coid_charset_warning's argument closes with "cancel stays fire-and-forget, which is honest: the node cannot confirm that an order EXISTS either way." An id that never existed is acknowledged exactly like one that did. Call node_snapshot to see whether the order actually left the book.

A malformed id is sent anyway, and that is deliberate

The human trade REPL refuses a submit --coid outside ^[A-Za-z0-9]{1,32}$ and only warns on a cancel naming one. This MCP surface does not warn at all — coid_charset_warning is wired into the REPL alone.

The asymmetry is argued rather than accidental. A submit is minting an id, so insisting on a charset every venue accepts costs one retype. A cancel names an id that already exists at the node, and this client is not the only thing that puts orders there: submit_order passes an agent-supplied client_order_id through unvalidated, and lower_command requires only that an id be non-empty. So an order with a coid outside that charset can exist — and refusing to cancel it would make a live order uncancellable from the console, to enforce a client-side convention. That trade is unacceptable in a tool whose reason to exist includes flattening something in a hurry.

Outcomes

Server::execute awaits this command's own ticket for ACK_WAIT, two seconds. accepted returns sent: true with the echoed id; a refusal is an error result carrying the node's reason; a timeout returns outcome: "unknown"; a dropped control connection is an error result saying the outcome is unknown and it may have executed. Both ambiguous cases end the same way — check node_snapshot before retrying.

To clear a whole book instead of one order, use mass_cancel; to change an order rather than withdraw it, use modify. The states an order passes through on its way out are described in Order lifecycle.

Cancel order a1b2c3d47 — it is stale after the feed gap.

On this page