Hypothetical
2 tools in this category.
Overview
Hypothetical includes 2 tools for this workflow area.
Available tools: list_hypotheticals, track_hypothetical.
Use the parameter tables and examples below as the canonical request contract.
list_hypotheticals
Lists shadow-tracked hypothetical trades and scores them. Individual results are newest first (by when they were recorded) and trimmed by limit (1-200, default 50); aggregate and groups always cover EVERY match, not just the page. Filters: from and to (UTC ISO, on when it was recorded), verdict (any case), run_id, symbol (resolved like track_hypothetical, so USDJPY finds USDJPYm), status (pending, open, closed).
Each result has status, filled, fill_price, fill_time, outcome (tp, sl, expired), exit_price, closed_time (UTC), risk (price distance entry to sl), realized_r (profit as a multiple of risk; null if it never filled), mae_r and mfe_r (largest adverse and favourable move after the fill bar, non-negative multiples of risk), current_r while open, ambiguous_bar, bars_processed and the inputs it was recorded with.
aggregate has count, filled, fill_rate (filled over filled + expired unfilled), closed, wins (outcome tp), win_rate (wins over closed filled), mean_r, median_r, total_r, mean_mae_r, mean_mfe_r (all over filled results that have closed), expired_unfilled, open and pending. Open and pending ones are counted but never enter the R statistics. group_by splits the same figures by verdict, symbol, run_id, side, entry_type (largest group first): group_by=verdict shows, for example, the average R of VETO candidates against PROCEED ones.
Simulation model (fixed, so results are comparable with each other, not with an account): M1 bars are bid prices and the spread seen when the hypothetical is recorded is held constant, ask = bid + spread. A buy limit fills when a bar's low + spread reaches the entry (at the entry, or at open + spread if the bar gaps below it); a buy stop when high + spread reaches it (at the entry, or worse on a gap); a sell limit when the high reaches it; a sell stop when the low reaches it; market fills at once at the entry you give. A long exits at bid, a short at ask. The stop is hit when the bar reaches sl, the take-profit when it reaches tp; a gap through either exits at the open, on the fill bar too. A bar that touches both counts as the STOP. On the bar that fills the order the stop still counts but a take-profit touch does not (it may have come before the fill), so the position stays open; both set ambiguous_bar. No commission, swap or slippage beyond gaps. Requires the read capability.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
from | string | No | — | — |
to | string | No | — | — |
verdict | string | No | — | — |
run_id | string | No | — | — |
symbol | string | No | — | — |
status | string | No | — | (one of: pending, open, closed) |
group_by | string | No | — | (one of: verdict, symbol, run_id, side, entry_type) |
limit | integer | No | — | — |
Example Request
{
"tool": "list_hypotheticals",
"arguments": {}
}track_hypothetical
Records a candidate trade that was not taken (a veto, a pass, a not-yet) so it can be scored against what the market then did. The platform simulates it forward by itself, with no agent running, using ONLY M1 bars that open after the latest bar that existed now, and only once they have closed; nothing known at this moment decides the outcome.
run_id links it to the debate that produced it (the same id you use in write_trade_note) and verdict is your own label, e.g. VETO or PROCEED (stored upper-case). side is buy or sell. entry_type: market (taken as filled at entry, which must be within max(2 x spread, 5 points) of the ask for a buy or the bid for a sell, with sl and tp not already crossed), limit (entry below the ask for a buy, above the bid for a sell) or stop (entry above the ask for a buy, below the bid for a sell); a limit or stop that would fill at once is refused. Prices are PRICES, not points: for a buy sl < entry < tp, for a sell tp < entry < sl. risk = |entry - sl| and every R below is a multiple of it. expiry is a future UTC ISO time (default 7 days, at most 30): an unfilled order lapses then, an open position closes at the last bar before it.
Simulation model (fixed, so results are comparable with each other, not with an account): M1 bars are bid prices and the spread seen when the hypothetical is recorded is held constant, ask = bid + spread. A buy limit fills when a bar's low + spread reaches the entry (at the entry, or at open + spread if the bar gaps below it); a buy stop when high + spread reaches it (at the entry, or worse on a gap); a sell limit when the high reaches it; a sell stop when the low reaches it; market fills at once at the entry you give. A long exits at bid, a short at ask. The stop is hit when the bar reaches sl, the take-profit when it reaches tp; a gap through either exits at the open, on the fill bar too. A bar that touches both counts as the STOP. On the bar that fills the order the stop still counts but a take-profit touch does not (it may have come before the fill), so the position stays open; both set ambiguous_bar. No commission, swap or slippage beyond gaps.
The symbol may omit the broker's suffix (USDJPY becomes USDJPYm); several matches are refused with the candidates. The same run cannot track the same symbol, side and entry_type again while the first is unresolved (DUPLICATE with the existing record). At most 500 unresolved per terminal. Needs the terminal connected and an EA that supports time-range bars (1.404 or later), otherwise ea_upgrade_required. When it resolves a journal entry (tag shadow, kind outcome, with the run_id) is written. Closed results are kept for 180 days.
Returns the record: status (pending, open, closed), filled, outcome (tp, sl, expired or null), realized_r, mae_r, mfe_r, times in UTC, the spread used and simulation_starts_after. dry_run=true (default false) runs every check, including the live price, and shows what would be stored without storing it. Requires the read capability.
This tool can affect a live trading account. dry_run defaults to true — pass dry_run: false explicitly to execute for real.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
run_id | string | Yes | — | — |
symbol | string | Yes | — | — |
side | string | Yes | — | (one of: buy, sell) |
entry_type | string | Yes | — | (one of: market, limit, stop) |
entry | number | Yes | — | — |
sl | number | Yes | — | — |
tp | number | Yes | — | — |
verdict | string | Yes | — | — |
expiry | string | No | — | — |
notes | string | No | — | — |
dry_run | boolean | No | false | — |
Example Request
{
"tool": "track_hypothetical",
"arguments": {
"run_id": "run_id_value",
"symbol": "EURUSD",
"side": "buy",
"entry_type": "market",
"entry": 1,
"sl": 1,
"tp": 1,
"verdict": "verdict_value",
"dry_run": false
}
}Usage Notes
- Keep
dry_run: trueuntil you have validated symbol, lot size, and expected execution behavior.