Trading Plan Specification
A minimal, machine-parseable format that encodes a complete trade plan — direction, entry zone, risk limits, and optional execution rules — in a single structured JSON object.
What Is a TPS Plan?
After the Trader agent produces its narrative investment plan, Flowdeck automatically generates a TPS (Trading Plan Specification) — a compact JSON object that captures the same decision in a structured, unambiguous format. You can find it in the Trader tab of any AI Analysis report.
The TPS plan answers the five questions every trade needs: what (instrument), which direction (side), where to enter (entry.near), where to stop out (risk.stop), and how much to risk (risk.max_loss). Optional fields add execution detail: entry confirmation conditions, take-profit targets, trailing stops, volatility guards, and invalidation rules.
Because the plan is structured JSON — not prose — it is unambiguous. Every field has a defined type and meaning. The Trader agent fills in the fields using Pydantic-validated structured output, so the plan always conforms to the schema.
Where to Find It
- Open any stock page (e.g.
/tickers/MAN). - Scroll to the AI Analysis section.
- Click the Trader tab.
- The TPS plan appears as a syntax-highlighted JSON block below the narrative text.
Example Plan
{ "instrument": "MAN", "timeframe": "1D", "side": "short", "entry": { "near": "25.15 ±1%", "confirm": ["rsi > 60", "close < ma20"] }, "risk": { "max_loss": "1%", "stop": 28.00, "max_position": "4%", "invalidate": "close > 28 for 2d -> exit" }, "take_profit": { "tp1": "22.00 sell 50%", "trail": "4%" }, "vol_guard": "atr20 > 1.5x avg -> reduce 30%" }
Field Reference
| Field | Required | Type | Example | Description |
|---|---|---|---|---|
| instrument | yes | string | MAN | Ticker symbol of the instrument being traded. |
| timeframe | yes | string | 1D | Candle resolution at which trade rules are evaluated (e.g. 1D, 4H, 15m). Flowdeck analyses use daily (1D) data. |
| side | yes | long | short | short | Trade direction. "long" for BUY/HOLD-long positions, "short" for SELL/SHORT positions. |
| entry.near | yes | number or band | 25.15 or "25.15 ±1%" | Entry trigger. A single price number, or a price-band string allowing a tolerance zone. |
| risk.max_loss | yes | percent string | "1%" | Maximum allowed portfolio loss for this trade. Default is "1%" when not stated. |
| risk.stop | yes | number | 24.00 | Hard stop-loss price. Exit immediately when this level is breached. |
| entry.scale | no | string | "40/30/30" | Tranche allocation of the intended position. "100" means enter all at once; "40/30/30" means three tranches. |
| entry.confirm | no | list of strings | ["rsi < 45", "macd_hist rising_2"] | Confirmation conditions. All must evaluate true before entry is allowed. |
| risk.max_position | no | percent string | "5%" | Maximum exposure allowed for this instrument as a percentage of portfolio. |
| risk.invalidate | no | rule string | "close > 28 for 2d -> exit" | Persistence-based exit rule. If the condition holds for N days, the trade thesis is invalidated and the position is exited. |
| take_profit.tp1 | no | rule string | "30.00 sell 50%" | First take-profit target. Sell the specified percentage of the position when price reaches the target. |
| take_profit.trail | no | percent string | "4%" | Trailing stop distance applied to the remaining position after tp1 is hit. |
| vol_guard | no | rule string | "atr20 > 1.5x avg -> reduce 30%" | Volatility guard. Reduces exposure when a volatility condition is met. |
| add_if | no | rule string | "macd bull & close > ma50 -> max_position 7%" | Conditional position increase. Raises the maximum allowed exposure when a condition is met. |
Rule String Syntax
Several optional fields use a rule string — a compact expression that encodes a condition and an action:
invalidatepattern:CONDITION -> exit"close > 28 for 2d -> exit"Exit the trade if the condition persists for N days.
take_profit.tp1pattern:PRICE sell PERCENT%"30.00 sell 50%"Sell the specified percentage when price reaches the target.
vol_guardpattern:CONDITION -> reduce PERCENT%"atr20 > 1.5x avg -> reduce 30%"Reduce exposure when volatility exceeds a threshold.
add_ifpattern:CONDITION -> max_position PERCENT%"macd bull & close > ma50 -> max_position 7%"Increase max allowed exposure when a condition is met.
How It Is Generated
The TPS plan is produced by the Trader agent as part of its structured output — in the same LLM call that produces the narrative investment plan. The agent uses with_structured_output with a Pydantic model (TpsPlan) that mirrors the JSON schema exactly. This means:
- The LLM fills typed fields, not free-form text — schema compliance is enforced by Pydantic before serialization.
- Required fields (
instrument,timeframe,side,entry.near,risk.stop,risk.max_loss) are always present. - Optional fields are only included when the agent can infer them from the analysis — fabricated prices are never added.
- The validated object is serialized to JSON via
json.dumpsand stored alongside the narrative report.
The TPS plan is stored in the report database and served through the API as part of the Trader report data. It is displayed in the Trader tab of the AI Analysis section on every stock page.
Limitations & Freshness
The TPS plan is generated from daily (1D) data — the same resolution used by all Flowdeck analysts. This means:
- Directional thesis (side, narrative) remains useful for days to weeks — it is based on fundamentals, news, and macro context which change slowly.
- Price levels (entry.near, risk.stop, take_profit.tp1) decay within 1–3 trading days as the market moves. Treat them as reference zones, not exact orders.
- The
risk.invalidaterule is designed to auto-expire the plan if the thesis breaks — e.g. "close > 28 for 2d → exit". - A report older than 3–5 trading days should be treated as directional context only. Generate a fresh analysis for updated price levels.
TPS-YAML v0.1 is an internal specification. The JSON schema is available at backend/TPS/TPS-YAML-v0.1.schema-1.json.