Learn / AI in Trading

Why a trade plan should be structured output

Ask a model what it thinks and you get a paragraph. Ask it for a structured plan and you get an object a program can validate, reject, log and compare. That difference is most of the engineering value of AI-assisted trading.

The prose is what people want. The object is what makes the setup safe.

What prose cannot do

A model saying “this looks like a reasonable long here, with a stop below the recent low and a target around the prior high” is useful to read and useless to a program.

  • Cannot be validated. No field to check against a position cap.
  • Cannot be rejected. A limit can refuse a number; it cannot refuse a paragraph.
  • Cannot be logged comparably. Ten paragraphs are ten paragraphs. Ten objects are a dataset.
  • Cannot be approved precisely. You are approving a description, and the order gets constructed separately. Those two can disagree — which is one of the failure modes in designing an approval workflow.
  • Hides omissions. Prose that does not mention size reads fine. A schema with a missing required field does not.

That last point is underrated. A vague plan and a specific plan look similar in prose, and the vagueness is often the actual problem.

A minimal schema

{
  "symbol": "BTC/USDT",
  "side": "long",
  "entry": 60000,
  "stop": 58800,
  "target": 63600,
  "size": 0.0833,
  "risk_pct": 1.0,
  "rationale": "…",
  "invalidation": "Close below 58800 breaks the structure this relies on",
  "confidence": "medium"
}

Every field is there for a reason.

stop is required, and separate from invalidation. One is a price, the other is why. Forcing both prevents the stop that exists only because a stop field existed — see how to choose a stop-loss level.

size and risk_pct are both present so they can be cross-checked. If size × |entry − stop| does not equal risk_pct × balance, something is wrong and a program can see it. The model does not have to be trusted with the arithmetic; it has to be consistent with it.

target makes R computable, which makes the plan comparable to every other plan through R multiples.

rationale is captured but not load-bearing. Log it — it is how you later find out whether particular kinds of reasoning correlate with outcomes — but do not let it be the most prominent thing on an approval screen. It is the most persuasive and least verifiable element there.

What you can do once it is an object

Validate before display. Recompute size from risk and stop distance; check symbol filters and step size — see symbol filters and minimum order sizes; check the direction of stop and target against side.

Reject before display. An order exceeding a position cap should never reach the approval screen. Asking a human to be the check on something a function can check is how approval fatigue sets in.

Compute the consequence. What this costs if the stop is hit, in currency and as a percentage of the account. That derived number is the most valuable thing on the card, because a decimal-place error is invisible in 0.5 BTC and obvious in “risks 41% of account”.

Log it as data. Now “were the plans I rejected worse than the ones I approved” is a query rather than a memory.

Diff proposal against execution. The order actually submitted can be compared field by field against the plan approved. They should match exactly, and checking is cheap.

MCP gives you the mechanism

MCP tools take an inputSchema in JSON Schema, and may declare an outputSchema — with the specification stating that when one is provided, servers MUST provide structured results conforming to it, and clients SHOULD validate against it.

The structuredContent field carries that result. So a plan-generating tool can be schema-constrained at the protocol level rather than by asking nicely in a prompt.

That is the right place for it. A schema is enforced; an instruction to “always include a stop” is a strong suggestion to a probabilistic process, which is the same distinction as a risk limit in code versus in a prompt.

The side effect worth having

Requiring structure changes what you ask.

“What do you think about BTC” produces a paragraph. Filling the schema requires answering: at what price is this wrong, what does that make the size, what is the R. Those are the questions that were being skipped, and half the benefit arrives before the model responds — in having to specify the question.

It also makes vagueness visible. A model that cannot name an invalidation level has told you something useful, and prose would have concealed it behind plausible hedging.

FAQ

Why should an AI trade plan be structured rather than prose?

Because a program can validate, reject, log and diff an object, and can do none of those with a paragraph. Structure lets limits refuse a plan before a human sees it, makes plans comparable across time, and ensures the thing you approve is the thing that gets submitted.

What fields should a trade plan include?

At minimum symbol, side, entry, stop, target, size, risk percentage, rationale and a separate invalidation condition. Including both size and risk percentage lets a program cross-check them against the stop distance, so the model does not have to be trusted with the arithmetic — only to be consistent with it.

Can MCP enforce a response schema?

Yes. Tools may declare an outputSchema, and the specification states that servers must return structured results conforming to it and clients should validate them. That places the constraint at the protocol level rather than in a prompt instruction, which is the difference between an enforced schema and a strong suggestion.

Does structured output make the model’s analysis better?

Not its market opinion, which is the part it is weakest at anyway. What improves is everything around it: omissions become visible, arithmetic becomes checkable, and the question you asked becomes specific enough to answer. That is where the practical gain is.