Skip to main content
Glama

Backtest Strategy

backtest_strategy
Read-only

Backtest a rule-based strategy on TraderWAI historical 1-minute data and get every trade plus a summary (win rate, total R, drawdown). It uses the SAME rules and engine as create_conditional_order, so a rule that looks good can be turned into a live conditional order. Pure calculation on the server, no AI: use it whenever the user asks to backtest or "how would this have worked" — do not compute backtests yourself from get_ohlc candles. Levels can be daily references so the rule works every day: {"ref":"session_high","session":"asia"} (asia 00:00-07:00, london 07:00-16:00, new_york 13:00-21:00 UTC), {"ref":"range_high","start":"00:00","end":"06:00"}, {"ref":"prev_day_low"}; the rule is armed each day once its levels are known. Example — "buy EUR/USD when it breaks the Asian high": symbol EUR_USD, conditions [{"type":"close_above","timeframe":"M15","level":{"ref":"session_high","session":"asia"}},{"type":"time_window","start":"07:00","end":"12:00"}], trade {"side":"buy","stop":{"type":"level","ref":{"ref":"session_low","session":"asia"}},"target":{"type":"rr","value":2},"closeAt":"20:00"}. Example — "sell gold when it sweeps the Asian high": conditions [{"type":"sweep_above","timeframe":"M15","level":{"ref":"session_high","session":"asia"},"maxCandles":2}], trade {"side":"sell","stop":{"type":"wick","bufferPips":20},"target":{"type":"rr","value":2}}. Indicators and trend filters: any level can be {"ref":"indicator","indicator":"sma|ema|rsi|atr|highest|lowest","timeframe":"D1","period":50}, {"ref":"price"}, {"ref":"day_open"} or {"ref":"day_high","daysAgo":2}; combine them with compare (e.g. {"type":"compare","left":{"ref":"price"},"op":"above","right":{"ref":"indicator","indicator":"ema","timeframe":"D1","period":50}}) and candle_direction (e.g. yesterday bullish). Indicators use closed candles only. Example — "buy gold on the first retest of a bullish M15 FVG in London": conditions [{"type":"fvg_retest","timeframe":"M15","direction":"bullish","maxCandles":20},{"type":"time_window","start":"07:00","end":"12:00"}], trade {"side":"buy","stop":{"type":"wick","bufferPips":10},"target":{"type":"rr","value":2}} (the wick stop goes beyond the gap's far edge). Limit entries and time exits: trade.entry {"type":"limit","at":{"type":"fvg","point":"midpoint"},"expiryMinutes":60} waits for price to come back to the limit (unfilled signals are reported), trade.maxMinutes closes after N minutes, and the target can be "none" with a time exit. Example — "when a bearish M15 FVG forms on gold, sell limit at its midpoint, stop above the gap, 2R or close after 2 hours": conditions [{"type":"fvg_formed","timeframe":"M15","direction":"bearish"}], trade {"side":"sell","entry":{"type":"limit","at":{"type":"fvg","point":"midpoint"},"expiryMinutes":60},"stop":{"type":"wick","bufferPips":20},"target":{"type":"rr","value":2},"maxMinutes":120}. Example — "buy the break and retest of today's 08:00-10:00 UTC range high": conditions [{"type":"retest","timeframe":"M15","direction":"up","level":{"ref":"range_high","start":"08:00","end":"10:00"},"maxCandles":10}], trade {"side":"buy","stop":{"type":"wick","bufferPips":5},"target":{"type":"rr","value":2}} (the wick stop goes below the retest candle; same rule and result as a live conditional). A limit entry at a level can be shifted with trade.entry.at.pips (positive above, negative below the level). COSTS: costs {"spreadPips","slippagePips","commissionPerLot" (USD, gold/silver/USD forex) or "commissionPips"} are charged on buys AND sells and the result shows R gross and net (spreadPips alone works the same). Always add realistic costs for strategies with small stops (M1/M5). RESULT DETAIL: every trade has its stop size in pips, MFE and MAE in R (how far it went for / against before closing), and the summary breaks the result down by month, by halves of the period, by weekday and entry hour, with profit factor and how many trades reached +1R…+4R: use it to choose the target and stop instead of running one backtest per variant; allTrades:true lists every trade (up to 300). STOP AT THE GAP: trade.stop {"type":"fvg","edge":"far","bufferPips":30} puts the stop beyond the far edge of the fvg_retest/fvg_formed gap, and "edge":"pattern" beyond the high/low of the three candles that form it; with a limit entry at the far edge use "pattern" (a far-edge stop would sit right next to the entry). trade.minStopPips/maxStopPips skip signals with a stop outside that size (counted). MANAGEMENT: trade.management {"breakevenAtR":1,"partials":[{"atR":1,"closePct":50}]} moves the stop to entry at +1R and closes half at +1R. LOCAL MARKET TIME: time_window, range_high/range_low and trade.closeAt accept "timezone" (e.g. Europe/London, America/New_York), so a London 08:00-11:00 window is measured at the same market hour in summer and winter. MARKET STRUCTURE: swings, BOS/CHoCH, order blocks, flip zones (broken base), Fibonacci of the last impulse, FVGs and equal highs/lows are detected candle by candle without look-ahead (see the condition types). Example — "sell gold on the first retest of a bearish order block + Fibonacci 0.5-0.618 + broken base overlap on M15, rejection candle on M5, bearish day, stop above the zone, target the last swing low, exit if no new low in 6 M5 candles": conditions [{"type":"bos","timeframe":"M15","direction":"bearish"},{"type":"confluence","direction":"bearish","zones":[{"zone":"order_block","timeframe":"M15"},{"zone":"flip_zone","timeframe":"M15"},{"zone":"fib_zone","timeframe":"M15","from":0.5,"to":0.618}],"min":2,"trigger":"rejection","confirmTimeframe":"M5","maxTouches":3},{"type":"compare","left":{"ref":"price"},"op":"below","right":{"ref":"day_open"}}], trade {"side":"sell","stop":{"type":"zone","edge":"far","bufferPips":20},"target":{"type":"level","ref":{"ref":"swing_low","timeframe":"M15"}},"management":{"exitIfNoProgress":{"candles":6,"timeframe":"M5"}}}. Results are broken down by zone / combination. Selective setups give few trades: use long periods, and sensitivity:true reruns the rule with neighbouring parameters (swing strength ±1, target ±0.5R) to see if the result holds. TRAILING: trade.trailing true moves the stop behind price at the initial stop distance (same rule as trailing: true on live orders). Not supported: other chart patterns (head and shoulders, triangles…), news, ATR or candle trailing stops. History available: 2 years of 1-minute candles (since 31 Oct 2024) on forex, gold, silver, crypto, indices and oil. Plan limits: Free = last 14 days and 5 backtests per day; Plus = 6 months and 20 per day; Trader = 1 year and 50 per day; Max = all history, unlimited. One backtest covers at most 1 year (2 years on Max) and up to 2000 trades: split longer periods. Works with the market closed (weekends) and without a broker account.

Input Schema

NameRequiredDescriptionDefault
toNoEnd (ISO 8601, default now)
daysNoPeriod: the last N days (default 7)
fromNoOr an explicit start (ISO 8601)
costsNoTrading costs charged on every trade (buys and sells): the result shows R gross and net of costs. E.g. gold {"spreadPips":30,"commissionPerLot":7}
tradeYesSide, stop, target and optional daily close time
symbolYesSymbol (e.g. EUR_USD, XAU_USD, NAS100_USD).
allTradesNotrue: list every trade of the period (up to 300) instead of the latest 40
conditionsYesEntry rule (all conditions must be met, max 5). Same types as create_conditional_order except at_time
spreadPipsNoSpread in pips, charged on buys and sells (same as costs.spreadPips)
sensitivityNotrue: also run the rule with neighbouring parameters (swing strength ±1 for structure conditions, target ±0.5R) and report each result, to check it is not fitted to the past

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed34 schema fields changed
    • addedInput schema / properties / conditions / items / properties / baseCandles
      Added value: +{
      +  "description": "flip_zone: minimum candles of the base (2-20, default 3)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / baseRangeAtr
      Added value: +{
      +  "description": "flip_zone: maximum range of the base in ATR(14) (0.2-5, default 1)",
      +  "type": "number"
      +}
    • addedInput schema / properties / conditions / items / properties / confirmStrength
      Added value: +{
      +  "description": "trigger \"choch\": swing strength on the confirmTimeframe (1-10, default 2)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / confirmTimeframe
      Added value: +{
      +  "description": "zone/confluence with trigger close/rejection (default the zone timeframe) or choch (required, lower than the zone timeframe)",
      +  "enum": [
      +    "M1",
      +    "M5",
      +    "M15",
      +    "M30",
      +    "H1",
      +    "H4",
      +    "D1"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / conditions / items / properties / from
      Added value: +{
      +  "description": "fib_zone: lower retracement level (default 0.5)",
      +  "type": "number"
      +}
    • changedInput schema / properties / conditions / items / properties / level / anyOf
      Previous value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "daysAgo": {
      -        "description": "day_high/day_low/day_close: 1 = yesterday, 2 = the day before…; day_open: 0 = today",
      -        "type": "integer"
      -      },
      -      "end": {
      -        "description": "range_high/range_low: HH:MM UTC (same day, after start)",
      -        "type": "string"
      -      },
      -      "indicator": {
      -        "description": "ref \"indicator\": highest/lowest = highest high / lowest low of the last N candles",
      -        "enum": [
      -          "sma",
      -          "ema",
      -          "rsi",
      -          "atr",
      -          "highest",
      -          "lowest"
      -        ],
      -        "type": "string"
      -      },
      -      "period": {
      -        "description": "ref \"indicator\": period (e.g. 50)",
      -        "type": "integer"
      -      },
      -      "ref": {
      -        "enum": [
      -          "session_high",
      -          "session_low",
      -          "range_high",
      -          "range_low",
      -          "prev_day_high",
      -          "prev_day_low",
      -          "prev_day_close",
      -          "day_high",
      -          "day_low",
      -          "day_open",
      -          "day_close",
      -          "indicator",
      -          "price"
      -        ],
      -        "type": "string"
      -      },
      -      "session": {
      -        "description": "session_high/session_low: asia 00:00-07:00, london 07:00-16:00, new_york 13:00-21:00 UTC",
      -        "enum": [
      -          "asia",
      -          "london",
      -          "new_york"
      -        ],
      -        "type": "string"
      -      },
      -      "shift": {
      -        "description": "ref \"indicator\": 0 = last closed candle (default), 1 = the one before…",
      -        "type": "integer"
      -      },
      -      "start": {
      -        "description": "range_high/range_low: HH:MM UTC",
      -        "type": "string"
      -      },
      -      "timeframe": {
      -        "description": "ref \"indicator\": candle timeframe",
      -        "enum": [
      -          "M1",
      -          "M5",
      -          "M15",
      -          "M30",
      -          "H1",
      -          "H4",
      -          "D1"
      -        ],
      -        "type": "string"
      -      },
      -      "timezone": {
      -        "description": "range_high/range_low: IANA time zone (e.g. Europe/London, America/New_York): the HH:MM times are local market time, so the same window follows the market in summer and winter (default UTC); the range must fall within the UTC day",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "ref"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "daysAgo": {
      +        "description": "day_high/day_low/day_close: 1 = yesterday, 2 = the day before…; day_open: 0 = today",
      +        "type": "integer"
      +      },
      +      "direction": {
      +        "description": "ref \"fib\": only if the last impulse goes this way (default any)",
      +        "enum": [
      +          "bullish",
      +          "bearish",
      +          "any"
      +        ],
      +        "type": "string"
      +      },
      +      "end": {
      +        "description": "range_high/range_low: HH:MM UTC (same day, after start)",
      +        "type": "string"
      +      },
      +      "indicator": {
      +        "description": "ref \"indicator\": highest/lowest = highest high / lowest low of the last N candles",
      +        "enum": [
      +          "sma",
      +          "ema",
      +          "rsi",
      +          "atr",
      +          "highest",
      +          "lowest"
      +        ],
      +        "type": "string"
      +      },
      +      "level": {
      +        "description": "ref \"fib\": the Fibonacci level (e.g. 0.618, 1, -0.27)",
      +        "type": "number"
      +      },
      +      "minImpulseAtr": {
      +        "description": "ref \"fib\": only impulses of at least this × ATR(14)",
      +        "type": "number"
      +      },
      +      "minSwingAtr": {
      +        "description": "swing_high/swing_low/fib: ignore swings that stand out less than this × ATR(14) (default 0)",
      +        "type": "number"
      +      },
      +      "nth": {
      +        "description": "swing_high/swing_low: 1 = the last confirmed swing (default), 2 = the one before…",
      +        "type": "integer"
      +      },
      +      "period": {
      +        "description": "ref \"indicator\": period (e.g. 50)",
      +        "type": "integer"
      +      },
      +      "ref": {
      +        "description": "Daily references, indicators, price, or MARKET STRUCTURE (M5-D1, closed candles only, no look-ahead): swing_high / swing_low = the last confirmed swing high/low (nth 2 = the one before…; a swing is a high/low with `strength` candles on each side, default 3, confirmed when those candles close); fib = a Fibonacci level of the LAST IMPULSE (the move between the last two opposite swings), measured from its end: 0.5 / 0.618 / 0.786 retracements, 1 = the impulse start, -0.27 / -0.618 = extensions beyond its end (targets).",
      +        "enum": [
      +          "session_high",
      +          "session_low",
      +          "range_high",
      +          "range_low",
      +          "prev_day_high",
      +          "prev_day_low",
      +          "prev_day_close",
      +          "day_high",
      +          "day_low",
      +          "day_open",
      +          "day_close",
      +          "indicator",
      +          "price",
      +          "swing_high",
      +          "swing_low",
      +          "fib"
      +        ],
      +        "type": "string"
      +      },
      +      "session": {
      +        "description": "session_high/session_low: asia 00:00-07:00, london 07:00-16:00, new_york 13:00-21:00 UTC",
      +        "enum": [
      +          "asia",
      +          "london",
      +          "new_york"
      +        ],
      +        "type": "string"
      +      },
      +      "shift": {
      +        "description": "ref \"indicator\": 0 = last closed candle (default), 1 = the one before…",
      +        "type": "integer"
      +      },
      +      "start": {
      +        "description": "range_high/range_low: HH:MM UTC",
      +        "type": "string"
      +      },
      +      "strength": {
      +        "description": "swing_high/swing_low/fib: candles on each side of a swing (1-10, default 3)",
      +        "type": "integer"
      +      },
      +      "timeframe": {
      +        "description": "ref \"indicator\": candle timeframe; swing_high/swing_low/fib: structure timeframe (M5-D1)",
      +        "enum": [
      +          "M1",
      +          "M5",
      +          "M15",
      +          "M30",
      +          "H1",
      +          "H4",
      +          "D1"
      +        ],
      +        "type": "string"
      +      },
      +      "timezone": {
      +        "description": "range_high/range_low: IANA time zone (e.g. Europe/London, America/New_York): the HH:MM times are local market time, so the same window follows the market in summer and winter (default UTC); the range must fall within the UTC day",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "ref"
      +    ],
      +    "type": "object"
      +  }
      +]
    • addedInput schema / properties / conditions / items / properties / maxAgeCandles
      Added value: +{
      +  "description": "zone: only zones created in the last N candles of its timeframe (1-500, default 50)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / maxTouches
      Added value: +{
      +  "description": "zone/confluence: 1 = first retest only (default), 2 = up to the second visit… (1-10)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / min
      Added value: +{
      +  "description": "confluence: how many zones must overlap (default 2)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / minCount
      Added value: +{
      +  "description": "equal_highs/equal_lows: swings needed (2-5, default 2)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / minImpulseAtr
      Added value: +{
      +  "description": "bos/choch/order_block/fib_zone: minimum size of the impulse (displacement) in ATR(14) (default 0)",
      +  "type": "number"
      +}
    • addedInput schema / properties / conditions / items / properties / minOverlapPips
      Added value: +{
      +  "description": "confluence: minimum height of the overlap in pips (default 0)",
      +  "type": "number"
      +}
    • addedInput schema / properties / conditions / items / properties / minSwingAtr
      Added value: +{
      +  "description": "Ignore swings that stand out less than this × ATR(14) (default 0)",
      +  "type": "number"
      +}
    • addedInput schema / properties / conditions / items / properties / pattern
      Added value: +{
      +  "description": "candle_pattern and trigger \"rejection\": pin_bar, engulfing or any (default)",
      +  "enum": [
      +    "pin_bar",
      +    "engulfing",
      +    "any"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / conditions / items / properties / shift / description
      Previous value: -"candle_direction: 1 = last closed candle (default), 2 = the one before…"New value: +"candle_direction / candle_pattern: 1 = last closed candle (default), 2 = the one before…"
    • addedInput schema / properties / conditions / items / properties / strength
      Added value: +{
      +  "description": "bos/choch/structure_trend/order_block/fib_zone/equal_*: candles on each side of a swing (1-10, default 3)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / conditions / items / properties / to
      Added value: +{
      +  "description": "fib_zone: upper retracement level (default 0.618)",
      +  "type": "number"
      +}
    • changedInput schema / properties / conditions / items / properties / tolerancePips / description
      Previous value: -"retest: how close to the level (in pips) counts as a retest (default 0)"New value: +"retest: how close to the level (in pips) counts as a retest (default 0); equal_highs/equal_lows: max distance between the swings (default 0.1 × ATR)"
    • changedInput schema / properties / conditions / items / properties / trigger / description
      Previous value: -"fvg_retest: touch = enter as soon as price reaches the gap (default); close = when the candle that returns to the gap closes"New value: +"fvg_retest: touch (default) or close. zone/confluence: touch (default), close, rejection or choch"
    • changedInput schema / properties / conditions / items / properties / trigger / enum
      Previous value: -[
      -  "touch",
      -  "close"
      -]New value: +[
      +  "touch",
      +  "close",
      +  "rejection",
      +  "choch"
      +]
    • changedInput schema / properties / conditions / items / properties / type / description
      Previous value: -"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, fvg_formed = a new gap just formed (pair it with a limit entry in the gap), time_window, days_of_week, retest {level, direction up|down, timeframe, maxCandles, tolerancePips} = break and retest of a level: a candle closes beyond the level (breakout), then within maxCandles candles (1-50, default 10) the first candle that comes back to it (within tolerancePips, default 0) and closes on the breakout side fires at its close; a close back inside before that cancels the breakout) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."New value: +"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, fvg_formed = a new gap just formed (pair it with a limit entry in the gap), time_window, days_of_week, retest {level, direction up|down, timeframe, maxCandles, tolerancePips} = break and retest of a level: a candle closes beyond the level (breakout), then within maxCandles candles (1-50, default 10) the first candle that comes back to it (within tolerancePips, default 0) and closes on the breakout side fires at its close; a close back inside before that cancels the breakout) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\". MARKET STRUCTURE (M5-D1, closed candles, no look-ahead; a swing = a high/low with `strength` candles on each side, default 3, known when those candles close): bos {timeframe, direction bullish|bearish, maxCandles, minImpulseAtr} = filter: the last break of structure (a close beyond the last swing) was in that direction within maxCandles candles (default 20); choch = the same but it reversed the previous break (change of character); structure_trend {timeframe, direction} = higher highs and higher lows (bullish) / lower highs and lower lows (bearish); candle_pattern {timeframe, pattern pin_bar|engulfing|any, direction, shift} = the last closed candle is a rejection candle. zone {zone, timeframe, direction, trigger, …} = ENTRY TRIGGER when price comes back to a live zone: zone order_block (last opposite candle before the impulse that broke structure; minImpulseAtr for displacement), flip_zone (a base of baseCandles+ candles within baseRangeAtr × ATR, default 3 and 1, broken by a close: broken support becomes resistance and vice versa), fib_zone (between the from/to retracements of the LAST impulse, default 0.5-0.618; OTE 0.62-0.79), fvg (fair value gap), equal_highs / equal_lows (2+ swing highs/lows within tolerancePips, default 0.1 × ATR: liquidity). A zone dies when a candle closes beyond it; maxAgeCandles (default 50) = how recent; maxTouches (default 1) = first retest only, 2 = up to the second visit… trigger: touch (default: the minute price reaches it), close (a confirmTimeframe candle touches it and closes back outside), rejection (same, with a pin bar / engulfing candle), choch (a CHoCH on a LOWER confirmTimeframe while price is in the zone: multi-timeframe entry). confluence {direction, zones:[{zone, timeframe, …}, …] (2-4), min (default 2), minOverlapPips, trigger…} = ENTRY TRIGGER at the OVERLAP of at least `min` live zones (the entry zone is their intersection; results are broken down by combination). The zone of the trigger is used by stop/limit \"zone\" (stop beyond its far edge, limit at its near edge / midpoint / far edge)."
    • changedInput schema / properties / conditions / items / properties / type / enum
      Previous value: -[
      -  "price_above",
      -  "price_below",
      -  "crosses_above",
      -  "crosses_below",
      -  "close_above",
      -  "close_below",
      -  "range_breakout",
      -  "consecutive_closes",
      -  "sweep_above",
      -  "sweep_below",
      -  "fvg_retest",
      -  "fvg_formed",
      -  "time_window",
      -  "days_of_week",
      -  "compare",
      -  "candle_direction",
      -  "retest"
      -]New value: +[
      +  "price_above",
      +  "price_below",
      +  "crosses_above",
      +  "crosses_below",
      +  "close_above",
      +  "close_below",
      +  "range_breakout",
      +  "consecutive_closes",
      +  "sweep_above",
      +  "sweep_below",
      +  "fvg_retest",
      +  "fvg_formed",
      +  "time_window",
      +  "days_of_week",
      +  "compare",
      +  "candle_direction",
      +  "retest",
      +  "bos",
      +  "choch",
      +  "structure_trend",
      +  "zone",
      +  "confluence",
      +  "candle_pattern"
      +]
    • addedInput schema / properties / conditions / items / properties / zone
      Added value: +{
      +  "description": "zone: the zone kind",
      +  "enum": [
      +    "order_block",
      +    "flip_zone",
      +    "fib_zone",
      +    "fvg",
      +    "equal_highs",
      +    "equal_lows"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / conditions / items / properties / zones
      Added value: +{
      +  "description": "confluence: 2-4 zones, e.g. [{\"zone\":\"order_block\",\"timeframe\":\"M15\"},{\"zone\":\"flip_zone\",\"timeframe\":\"M15\"},{\"zone\":\"fib_zone\",\"timeframe\":\"M15\",\"from\":0.5,\"to\":0.618}]",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "baseCandles": {
      +        "type": "integer"
      +      },
      +      "baseRangeAtr": {
      +        "type": "number"
      +      },
      +      "from": {
      +        "type": "number"
      +      },
      +      "maxAgeCandles": {
      +        "type": "integer"
      +      },
      +      "minCount": {
      +        "type": "integer"
      +      },
      +      "minGap": {
      +        "type": "number"
      +      },
      +      "minImpulseAtr": {
      +        "type": "number"
      +      },
      +      "minSwingAtr": {
      +        "type": "number"
      +      },
      +      "strength": {
      +        "type": "integer"
      +      },
      +      "timeframe": {
      +        "enum": [
      +          "M5",
      +          "M15",
      +          "M30",
      +          "H1",
      +          "H4",
      +          "D1"
      +        ],
      +        "type": "string"
      +      },
      +      "to": {
      +        "type": "number"
      +      },
      +      "tolerancePips": {
      +        "type": "number"
      +      },
      +      "zone": {
      +        "enum": [
      +          "order_block",
      +          "flip_zone",
      +          "fib_zone",
      +          "fvg",
      +          "equal_highs",
      +          "equal_lows"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "zone",
      +      "timeframe"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / sensitivity
      Added value: +{
      +  "description": "true: also run the rule with neighbouring parameters (swing strength ±1 for structure conditions, target ±0.5R) and report each result, to check it is not fitted to the past",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / trade / properties / entry / properties / at / properties / point / description
      Previous value: -"type \"fvg\": near edge, midpoint (default) or far edge"New value: +"type \"fvg\" / \"zone\": near edge, midpoint (default) or far edge"
    • changedInput schema / properties / trade / properties / entry / properties / at / properties / type / description
      Previous value: -"offset: N pips better than the signal price; price: fixed; level: a reference (Asian low, EMA…); fvg: inside the gap of an fvg condition"New value: +"offset: N pips better than the signal price; price: fixed; level: a reference (Asian low, EMA, Fibonacci level…); fvg: inside the gap of an fvg condition; zone: inside the zone of a zone/confluence condition"
    • changedInput schema / properties / trade / properties / entry / properties / at / properties / type / enum
      Previous value: -[
      -  "offset",
      -  "price",
      -  "level",
      -  "fvg"
      -]New value: +[
      +  "offset",
      +  "price",
      +  "level",
      +  "fvg",
      +  "zone"
      +]
    • changedInput schema / properties / trade / properties / management / description
      Previous value: -"Trade management while open: break-even and partial closes (checked after the stop on each 1-minute candle: worst case)"New value: +"Trade management while open: break-even and partial closes (checked after the stop on each 1-minute candle: worst case) and exits by price behaviour (no progress, compression). The same exits exist on live conditional orders (action.exitIfNoProgress / exitOnCompression)"
    • addedInput schema / properties / trade / properties / management / properties / exitIfNoProgress
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Close at the close of the candle when price has made no new high (buy) / low (sell) for N closed candles of that timeframe since entry, e.g. {\"candles\":6,\"timeframe\":\"M5\"}",
      +  "properties": {
      +    "candles": {
      +      "type": "integer"
      +    },
      +    "timeframe": {
      +      "enum": [
      +        "M1",
      +        "M5",
      +        "M15",
      +        "M30",
      +        "H1",
      +        "H4",
      +        "D1"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "candles",
      +    "timeframe"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / trade / properties / management / properties / exitOnCompression
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Close when the last N closed candles span less than maxRangeAtr × ATR(14) of that timeframe (price accumulating instead of moving), e.g. {\"candles\":6,\"timeframe\":\"M5\",\"maxRangeAtr\":0.8}",
      +  "properties": {
      +    "candles": {
      +      "type": "integer"
      +    },
      +    "maxRangeAtr": {
      +      "type": "number"
      +    },
      +    "timeframe": {
      +      "enum": [
      +        "M1",
      +        "M5",
      +        "M15",
      +        "M30",
      +        "H1",
      +        "H4",
      +        "D1"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "candles",
      +    "timeframe",
      +    "maxRangeAtr"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / trade / properties / stop / properties / edge / description
      Previous value: -"type \"fvg\": far edge (default; below a bullish gap / above a bearish gap), near edge, midpoint, or pattern = beyond the low/high of the three candles that form the gap"New value: +"type \"fvg\" / \"zone\": far edge (default; below a bullish zone / above a bearish zone), near edge, midpoint, or pattern = beyond the low/high of the three candles that form the gap (fvg)"
    • changedInput schema / properties / trade / properties / stop / properties / type / description
      Previous value: -"pips: distance from entry; price: fixed price; level: a reference (the Asian low, an EMA…); wick: beyond the sweep wick (or the trigger candle extreme); atr: multiple × ATR from the entry; fvg: at an edge of the gap of the fvg_retest/fvg_formed condition (edge far by default) plus bufferPips"New value: +"pips: distance from entry; price: fixed price; level: a reference (the Asian low, an EMA, the last swing high…); wick: beyond the sweep wick (or the trigger / confirmation candle extreme); atr: multiple × ATR from the entry; fvg: at an edge of the gap of the fvg_retest/fvg_formed condition (edge far by default) plus bufferPips; zone: at an edge of the zone of the zone/confluence condition (edge far by default) plus bufferPips"
    • changedInput schema / properties / trade / properties / stop / properties / type / enum
      Previous value: -[
      -  "pips",
      -  "price",
      -  "level",
      -  "wick",
      -  "atr",
      -  "fvg"
      -]New value: +[
      +  "pips",
      +  "price",
      +  "level",
      +  "wick",
      +  "atr",
      +  "fvg",
      +  "zone"
      +]
  2. Changed16 schema fields changed
    • addedInput schema / properties / allTrades
      Added value: +{
      +  "description": "true: list every trade of the period (up to 300) instead of the latest 40",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / conditions / items / properties / end / description
      Previous value: -"time_window: HH:MM UTC"New value: +"time_window: HH:MM (UTC, or local time of timezone)"
    • changedInput schema / properties / conditions / items / properties / level / anyOf
      Previous value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "daysAgo": {
      -        "description": "day_high/day_low/day_close: 1 = yesterday, 2 = the day before…; day_open: 0 = today",
      -        "type": "integer"
      -      },
      -      "end": {
      -        "description": "range_high/range_low: HH:MM UTC (same day, after start)",
      -        "type": "string"
      -      },
      -      "indicator": {
      -        "description": "ref \"indicator\": highest/lowest = highest high / lowest low of the last N candles",
      -        "enum": [
      -          "sma",
      -          "ema",
      -          "rsi",
      -          "atr",
      -          "highest",
      -          "lowest"
      -        ],
      -        "type": "string"
      -      },
      -      "period": {
      -        "description": "ref \"indicator\": period (e.g. 50)",
      -        "type": "integer"
      -      },
      -      "ref": {
      -        "enum": [
      -          "session_high",
      -          "session_low",
      -          "range_high",
      -          "range_low",
      -          "prev_day_high",
      -          "prev_day_low",
      -          "prev_day_close",
      -          "day_high",
      -          "day_low",
      -          "day_open",
      -          "day_close",
      -          "indicator",
      -          "price"
      -        ],
      -        "type": "string"
      -      },
      -      "session": {
      -        "description": "session_high/session_low: asia 00:00-07:00, london 07:00-16:00, new_york 13:00-21:00 UTC",
      -        "enum": [
      -          "asia",
      -          "london",
      -          "new_york"
      -        ],
      -        "type": "string"
      -      },
      -      "shift": {
      -        "description": "ref \"indicator\": 0 = last closed candle (default), 1 = the one before…",
      -        "type": "integer"
      -      },
      -      "start": {
      -        "description": "range_high/range_low: HH:MM UTC",
      -        "type": "string"
      -      },
      -      "timeframe": {
      -        "description": "ref \"indicator\": candle timeframe",
      -        "enum": [
      -          "M1",
      -          "M5",
      -          "M15",
      -          "M30",
      -          "H1",
      -          "H4",
      -          "D1"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "ref"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "daysAgo": {
      +        "description": "day_high/day_low/day_close: 1 = yesterday, 2 = the day before…; day_open: 0 = today",
      +        "type": "integer"
      +      },
      +      "end": {
      +        "description": "range_high/range_low: HH:MM UTC (same day, after start)",
      +        "type": "string"
      +      },
      +      "indicator": {
      +        "description": "ref \"indicator\": highest/lowest = highest high / lowest low of the last N candles",
      +        "enum": [
      +          "sma",
      +          "ema",
      +          "rsi",
      +          "atr",
      +          "highest",
      +          "lowest"
      +        ],
      +        "type": "string"
      +      },
      +      "period": {
      +        "description": "ref \"indicator\": period (e.g. 50)",
      +        "type": "integer"
      +      },
      +      "ref": {
      +        "enum": [
      +          "session_high",
      +          "session_low",
      +          "range_high",
      +          "range_low",
      +          "prev_day_high",
      +          "prev_day_low",
      +          "prev_day_close",
      +          "day_high",
      +          "day_low",
      +          "day_open",
      +          "day_close",
      +          "indicator",
      +          "price"
      +        ],
      +        "type": "string"
      +      },
      +      "session": {
      +        "description": "session_high/session_low: asia 00:00-07:00, london 07:00-16:00, new_york 13:00-21:00 UTC",
      +        "enum": [
      +          "asia",
      +          "london",
      +          "new_york"
      +        ],
      +        "type": "string"
      +      },
      +      "shift": {
      +        "description": "ref \"indicator\": 0 = last closed candle (default), 1 = the one before…",
      +        "type": "integer"
      +      },
      +      "start": {
      +        "description": "range_high/range_low: HH:MM UTC",
      +        "type": "string"
      +      },
      +      "timeframe": {
      +        "description": "ref \"indicator\": candle timeframe",
      +        "enum": [
      +          "M1",
      +          "M5",
      +          "M15",
      +          "M30",
      +          "H1",
      +          "H4",
      +          "D1"
      +        ],
      +        "type": "string"
      +      },
      +      "timezone": {
      +        "description": "range_high/range_low: IANA time zone (e.g. Europe/London, America/New_York): the HH:MM times are local market time, so the same window follows the market in summer and winter (default UTC); the range must fall within the UTC day",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "ref"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / conditions / items / properties / start / description
      Previous value: -"time_window: HH:MM UTC"New value: +"time_window: HH:MM (UTC, or local time of timezone)"
    • addedInput schema / properties / conditions / items / properties / timezone
      Added value: +{
      +  "description": "time_window: IANA time zone (e.g. Europe/London) so start/end are local market time in summer and winter (default UTC)",
      +  "type": "string"
      +}
    • addedInput schema / properties / costs
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Trading costs charged on every trade (buys and sells): the result shows R gross and net of costs. E.g. gold {\"spreadPips\":30,\"commissionPerLot\":7}",
      +  "properties": {
      +    "commissionPerLot": {
      +      "description": "Round-turn commission in USD per standard lot (gold, silver and forex pairs with USD)",
      +      "type": "number"
      +    },
      +    "commissionPips": {
      +      "description": "Or the round-turn commission in pips (any symbol)",
      +      "type": "number"
      +    },
      +    "slippagePips": {
      +      "description": "Slippage in pips per fill (charged on entry and exit)",
      +      "type": "number"
      +    },
      +    "spreadPips": {
      +      "description": "Spread in pips, charged on buys AND sells",
      +      "type": "number"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedInput schema / properties / spreadPips / description
      Previous value: -"Spread in pips added to buy entries (default 0)"New value: +"Spread in pips, charged on buys and sells (same as costs.spreadPips)"
    • changedInput schema / properties / trade / properties / closeAt / description
      Previous value: -"HH:MM UTC: close any open trade at this time and take no new entries after it"New value: +"HH:MM (UTC, or local time of trade.timezone): close any open trade at this time and take no new entries after it"
    • addedInput schema / properties / trade / properties / management
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Trade management while open: break-even and partial closes (checked after the stop on each 1-minute candle: worst case)",
      +  "properties": {
      +    "breakevenAtR": {
      +      "description": "Move the stop to the entry once price reaches +N R (e.g. 1)",
      +      "type": "number"
      +    },
      +    "partials": {
      +      "description": "Up to 3 partial closes, e.g. [{\"atR\":1,\"closePct\":50}]",
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "atR": {
      +            "description": "Close part of the trade at +N R (below the target)",
      +            "type": "number"
      +          },
      +          "closePct": {
      +            "description": "Percent of the position closed there (1-99; all partials together < 100)",
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "atR",
      +          "closePct"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / trade / properties / maxStopPips
      Added value: +{
      +  "description": "Skip signals whose stop is farther than this many pips",
      +  "type": "number"
      +}
    • addedInput schema / properties / trade / properties / minStopPips
      Added value: +{
      +  "description": "Skip signals whose stop is closer than this many pips (counted as \"discarded by stop size\")",
      +  "type": "number"
      +}
    • addedInput schema / properties / trade / properties / stop / properties / edge
      Added value: +{
      +  "description": "type \"fvg\": far edge (default; below a bullish gap / above a bearish gap), near edge, midpoint, or pattern = beyond the low/high of the three candles that form the gap",
      +  "enum": [
      +    "far",
      +    "near",
      +    "midpoint",
      +    "pattern"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / trade / properties / stop / properties / type / description
      Previous value: -"pips: distance from entry; price: fixed price; level: a reference (the Asian low, an EMA…); wick: beyond the sweep wick (or the trigger candle extreme); atr: multiple × ATR from the entry"New value: +"pips: distance from entry; price: fixed price; level: a reference (the Asian low, an EMA…); wick: beyond the sweep wick (or the trigger candle extreme); atr: multiple × ATR from the entry; fvg: at an edge of the gap of the fvg_retest/fvg_formed condition (edge far by default) plus bufferPips"
    • changedInput schema / properties / trade / properties / stop / properties / type / enum
      Previous value: -[
      -  "pips",
      -  "price",
      -  "level",
      -  "wick",
      -  "atr"
      -]New value: +[
      +  "pips",
      +  "price",
      +  "level",
      +  "wick",
      +  "atr",
      +  "fvg"
      +]
    • addedInput schema / properties / trade / properties / timezone
      Added value: +{
      +  "$ref": "#/properties/conditions/items/properties/timezone",
      +  "description": "IANA time zone for closeAt (e.g. Europe/London); default UTC"
      +}
    • addedInput schema / properties / trade / properties / trailing
      Added value: +{
      +  "description": "true: trailing stop — after each 1-minute candle the stop moves to best price minus the initial stop distance, only in favour (the same rule the broker applies to a live order or conditional with trailing: true)",
      +  "type": "boolean"
      +}
  3. Changed5 schema fields changed
    • changedInput schema / properties / conditions / items / properties / direction / description
      Previous value: -"range_breakout: up/down/any; candle_direction and fvg_retest: bullish/bearish"New value: +"range_breakout: up/down/any; retest: up/down; candle_direction and fvg_retest: bullish/bearish"
    • changedInput schema / properties / conditions / items / properties / maxCandles / description
      Previous value: -"sweep_above/sweep_below: candles allowed to close back inside (1-10, default 3); fvg_retest: how recent the gap must be (3-100 candles, default 20)"New value: +"sweep_above/sweep_below: candles allowed to close back inside (1-10, default 3); fvg_retest: how recent the gap must be (3-100 candles, default 20); retest: max candles between the breakout and the retest (1-50, default 10)"
    • addedInput schema / properties / conditions / items / properties / tolerancePips
      Added value: +{
      +  "description": "retest: how close to the level (in pips) counts as a retest (default 0)",
      +  "type": "number"
      +}
    • changedInput schema / properties / conditions / items / properties / type / description
      Previous value: -"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, fvg_formed = a new gap just formed (pair it with a limit entry in the gap), time_window, days_of_week) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."New value: +"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, fvg_formed = a new gap just formed (pair it with a limit entry in the gap), time_window, days_of_week, retest {level, direction up|down, timeframe, maxCandles, tolerancePips} = break and retest of a level: a candle closes beyond the level (breakout), then within maxCandles candles (1-50, default 10) the first candle that comes back to it (within tolerancePips, default 0) and closes on the breakout side fires at its close; a close back inside before that cancels the breakout) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."
    • changedInput schema / properties / conditions / items / properties / type / enum
      Previous value: -[
      -  "price_above",
      -  "price_below",
      -  "crosses_above",
      -  "crosses_below",
      -  "close_above",
      -  "close_below",
      -  "range_breakout",
      -  "consecutive_closes",
      -  "sweep_above",
      -  "sweep_below",
      -  "fvg_retest",
      -  "fvg_formed",
      -  "time_window",
      -  "days_of_week",
      -  "compare",
      -  "candle_direction"
      -]New value: +[
      +  "price_above",
      +  "price_below",
      +  "crosses_above",
      +  "crosses_below",
      +  "close_above",
      +  "close_below",
      +  "range_breakout",
      +  "consecutive_closes",
      +  "sweep_above",
      +  "sweep_below",
      +  "fvg_retest",
      +  "fvg_formed",
      +  "time_window",
      +  "days_of_week",
      +  "compare",
      +  "candle_direction",
      +  "retest"
      +]
  4. Changed2 schema fields changed
    • addedInput schema / properties / conditions / items / properties / trigger
      Added value: +{
      +  "description": "fvg_retest: touch = enter as soon as price reaches the gap (default); close = when the candle that returns to the gap closes",
      +  "enum": [
      +    "touch",
      +    "close"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / symbol / description
      Previous value: -"Symbol (e.g. EUR_USD, XAU_USD, NAS100_USD). Use list_symbols"New value: +"Symbol (e.g. EUR_USD, XAU_USD, NAS100_USD)."
  5. Changed8 schema fields changed
    • changedInput schema / properties / conditions / items / properties / type / description
      Previous value: -"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, time_window, days_of_week) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."New value: +"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, fvg_formed = a new gap just formed (pair it with a limit entry in the gap), time_window, days_of_week) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."
    • changedInput schema / properties / conditions / items / properties / type / enum
      Previous value: -[
      -  "price_above",
      -  "price_below",
      -  "crosses_above",
      -  "crosses_below",
      -  "close_above",
      -  "close_below",
      -  "range_breakout",
      -  "consecutive_closes",
      -  "sweep_above",
      -  "sweep_below",
      -  "fvg_retest",
      -  "time_window",
      -  "days_of_week",
      -  "compare",
      -  "candle_direction"
      -]New value: +[
      +  "price_above",
      +  "price_below",
      +  "crosses_above",
      +  "crosses_below",
      +  "close_above",
      +  "close_below",
      +  "range_breakout",
      +  "consecutive_closes",
      +  "sweep_above",
      +  "sweep_below",
      +  "fvg_retest",
      +  "fvg_formed",
      +  "time_window",
      +  "days_of_week",
      +  "compare",
      +  "candle_direction"
      +]
    • addedInput schema / properties / trade / properties / entry
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "How to enter once the rule fires",
      +  "properties": {
      +    "at": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "pips": {
      +          "type": "number"
      +        },
      +        "point": {
      +          "description": "type \"fvg\": near edge, midpoint (default) or far edge",
      +          "enum": [
      +            "near",
      +            "midpoint",
      +            "far"
      +          ],
      +          "type": "string"
      +        },
      +        "ref": {
      +          "$ref": "#/properties/conditions/items/properties/level/anyOf/1"
      +        },
      +        "type": {
      +          "description": "offset: N pips better than the signal price; price: fixed; level: a reference (Asian low, EMA…); fvg: inside the gap of an fvg condition",
      +          "enum": [
      +            "offset",
      +            "price",
      +            "level",
      +            "fvg"
      +          ],
      +          "type": "string"
      +        },
      +        "value": {
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "type"
      +      ],
      +      "type": "object"
      +    },
      +    "expiryMinutes": {
      +      "description": "limit: cancel if not filled after N minutes (1-1440, default 60); unfilled signals are counted",
      +      "type": "integer"
      +    },
      +    "type": {
      +      "description": "market (default): enter at the close of the signal candle; limit: wait for price to reach a limit price",
      +      "enum": [
      +        "market",
      +        "limit"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "type"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / trade / properties / maxMinutes
      Added value: +{
      +  "description": "Time exit: close the trade N minutes after entry (1-10080)",
      +  "type": "integer"
      +}
    • addedInput schema / properties / trade / properties / target / description
      Added value: +"Take profit (optional when the trade has a time exit)"
    • changedInput schema / properties / trade / properties / target / properties / type / description
      Previous value: -"rr: multiple of the risk (2 = 2R)"New value: +"rr: multiple of the risk (2 = 2R); none: no take profit (needs maxMinutes or closeAt)"
    • changedInput schema / properties / trade / properties / target / properties / type / enum
      Previous value: -[
      -  "rr",
      -  "pips",
      -  "price",
      -  "level"
      -]New value: +[
      +  "rr",
      +  "pips",
      +  "price",
      +  "level",
      +  "none"
      +]
    • changedInput schema / properties / trade / required
      Previous value: -[
      -  "side",
      -  "stop",
      -  "target"
      -]New value: +[
      +  "side",
      +  "stop"
      +]
  6. Changed6 schema fields changed
    • changedInput schema / properties / conditions / items / properties / direction / description
      Previous value: -"range_breakout: up/down/any; candle_direction: bullish/bearish"New value: +"range_breakout: up/down/any; candle_direction and fvg_retest: bullish/bearish"
    • addedInput schema / properties / conditions / items / properties / entry
      Added value: +{
      +  "description": "fvg_retest: touch (default) or midpoint of the gap",
      +  "enum": [
      +    "touch",
      +    "midpoint"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / conditions / items / properties / maxCandles / description
      Previous value: -"sweep_above/sweep_below: candles allowed to close back inside (1-10, default 3)"New value: +"sweep_above/sweep_below: candles allowed to close back inside (1-10, default 3); fvg_retest: how recent the gap must be (3-100 candles, default 20)"
    • addedInput schema / properties / conditions / items / properties / minGap
      Added value: +{
      +  "description": "fvg_retest: minimum gap size in price units",
      +  "type": "number"
      +}
    • changedInput schema / properties / conditions / items / properties / type / description
      Previous value: -"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, time_window, days_of_week) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."New value: +"Same as create_conditional_order (price_above/below, crosses_above/below, close_above/below, range_breakout, consecutive_closes, sweep_above/below, fvg_retest = first retest of a fair value gap, time_window, days_of_week) plus two backtest conditions: compare {left, op, right}: compares two values (numbers or references), op above / below / crosses_above / crosses_below — e.g. trend filters: price above the D1 EMA 50, D1 EMA 20 above D1 EMA 50, H1 RSI below 30, yesterday's high above the day before's; crosses_* can be the entry trigger (moving-average crossover). candle_direction {timeframe, direction bullish|bearish, shift}: the last closed candle of that timeframe (shift 1) closed up/down — e.g. \"yesterday was bullish\"."
    • changedInput schema / properties / conditions / items / properties / type / enum
      Previous value: -[
      -  "price_above",
      -  "price_below",
      -  "crosses_above",
      -  "crosses_below",
      -  "close_above",
      -  "close_below",
      -  "range_breakout",
      -  "consecutive_closes",
      -  "sweep_above",
      -  "sweep_below",
      -  "time_window",
      -  "days_of_week",
      -  "compare",
      -  "candle_direction"
      -]New value: +[
      +  "price_above",
      +  "price_below",
      +  "crosses_above",
      +  "crosses_below",
      +  "close_above",
      +  "close_below",
      +  "range_breakout",
      +  "consecutive_closes",
      +  "sweep_above",
      +  "sweep_below",
      +  "fvg_retest",
      +  "time_window",
      +  "days_of_week",
      +  "compare",
      +  "candle_direction"
      +]
  7. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, but the description adds substantial behavioral context beyond them: server-side pure calculation with no AI, available history, plan limits, cost simulation, result breakdowns, sensitivity checks, unsupported features, and behavior with markets closed. No contradiction with the annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and usage, but it is extremely long and dense, with repeated examples and duplicated guidance across sections. The length is partly justified by the complex nested schema, but it is not concise and could be tightened without losing key information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complex nested schema, lack of an output schema, and wide range of condition types, the description is highly complete. It explains return details, cost treatment, plan limits, unsupported features, and operational constraints that an agent needs in order to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already carries parameter semantics. The description adds meaningful value beyond it through concrete examples for levels, sessions, indicators, entries, stops, targets, management, costs, and timezone handling, though some of this repeats structured schema descriptions rather than introducing entirely new semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: backtest a rule-based strategy on TraderWAI historical 1-minute data, returning every trade plus a summary. It explicitly distinguishes the tool from create_conditional_order and get_ohlc by saying rules are shared with live conditionals and that the agent should not compute backtests from candles itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: 'use it whenever the user asks to backtest or how would this have worked' and a clear when-not alternative: 'do not compute backtests yourself from get_ohlc candles.' It also explains how backtest rules map to create_conditional_order live orders and notes plan/history limits that affect when the tool is applicable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources