Skip to content

Releases: tbraman-dev/nt8-mcp

nt8-mcp 1.5.0

Choose a tag to compare

@tbraman-dev tbraman-dev released this 30 Sep 08:03

nt8-mcp 1.5.0: Sim desk tools, NinjaScript lint, NT8 trade match

89 tools (was 79). Full list in CHANGELOG.md.

What is new

  • Sim desk. For the day after a platform crash. nt_desk_status reads the Strategies grid in
    one call: expected legs vs enabled vs Realtime, duplicates, orphaned orders, trace age, and legs
    silent past their decision time. Then gated repairs: nt_cancel_orphans (cancel working orders
    whose strategy instance is dead), nt_grid_remove (remove a dead row), nt_grid_enable and
    nt_desk_recover (re-enable allowlisted legs, one row per leg). Also nt_leg_decisions,
    nt_crash_report and nt_lock. Grid rows and order rows now carry strategy and owner ids.
  • nt_lint. A static scan of NinjaScript .cs files for known hazards (NT01-NT09):
    cross-instrument series in indicators, depth on a pool thread, Thread.Abort, unguarded file
    writes, network calls, strategies that never cancel their own orders on disable, Print spam,
    Process/Registry/Delete/Exit, sync Dispatcher.Invoke, hidden text. No NinjaTrader needed; also
    python scripts/nt_lint.py.
  • nt_match. Matches NinjaTrader's trades to a research trade list, per entry: % on date +
    side and on full outcome, same-bar stop/target ambiguity checked on 1-minute bars, news minutes
    flagged, a per-mismatch table and a PASS/FAIL gate (default 95%).
  • Strategy start on Sim. nt_strategy_start takes break_at_eod (default true, like a
    chartless backtest) and trading_hours, so a live run builds the same bars as its backtest.
    nt_backtest takes break_at_eod too. A started run survives a NinjaScript recompile.
  • Changed. orders.enabled no longer expires: delete it to disarm. Order entry, ATM and
    strategy start/stop no longer refuse because a broker connection is up (it is often a Sim
    account's price feed); the Simulator/Playback account check still refuses every real account.
    /ops/flatten flattens a Sim/Playback account whatever connection is up.
  • Fixes. A strategy start is no longer reported as failed while it runs. realtimeTrades
    agrees with realizedPnL. Multi-series indicators return their plot values, and each plot
    carries its last valid point.

Safety model

  • Read-only by default. Every write is opt-in through a file you create by hand
    (orders.enabled); no tool, script or test creates it.
  • Order, strategy and Sim desk writes reach Simulator and Playback accounts only, judged by the
    connection's provider, never by the account name.
  • Every write is a dry run first, then a signed confirm that works once, within 30 seconds, for
    exactly the plan the dry run showed. The Sim desk writes also need the local NT8 lock, and
    nt_grid_enable needs an allowlist file.

Upgrade

  1. Copy the new AddOn files into NinjaTrader: powershell -ExecutionPolicy Bypass -File scripts\install-addon.ps1 (it also adds the new NT8BridgeDesk.cs), then compile (F5 in the
    NinjaScript Editor, or nt8 nt_compile).
  2. Reinstall the server: pip install -e server.
  3. Restart your MCP client so it loads the new tools.
  4. Check: nt8 health reports addonVersion 1.5.0.

Known limitations

  • nt_grid_enable re-enables an existing row. NinjaTrader keeps a re-enabled strategy on its old
    compiled code.
  • The Sim desk writes rely on NinjaTrader behaviour that is not documented. Read nt_desk_status
    and the dry run before the first confirm.
  • The NT8 lock is advisory, enforced in the MCP server. It coordinates agents; it is not a
    security gate.
  • nt_match compares exit prices as given: a reference that records a time exit at a different
    bar will differ.
  • nt_lint is a pattern scan: it can miss a hazard and can raise a false alarm.

nt8-mcp 1.4.0

Choose a tag to compare

@tbraman-dev tbraman-dev released this 20 Sep 07:32

Added

  • Order module: brackets, close, reverse, and manage-any-order. nt_order_bracket sends an
    entry plus a stop and any number of targets under one plan and one confirm; exits are sized to
    the entry's real fill, not the requested quantity. nt_position_close and nt_position_reverse
    cancel one instrument's working orders on one account, then flatten it (reverse also enters
    the same quantity the other way). nt_order_change and nt_order_cancel now reach any
    working order on a Simulator/Playback account — a running strategy's stop, an ATM's target, a
    hand-placed order — and the plan names its owner (module / strategy <name> / atm /
    manual). One OCO pair per target, because NinjaTrader cancels every other live order in an
    OCO group when one fills or is cancelled: cancelling a target also cancels its own paired stop,
    never a sibling pair's. Caps raised to 10 contracts per order / 20 working orders per account /
    60 submits per minute, with config-file ceilings of 100 / 100 / 600. Full contract:
    docs/api/orders.md.
  • ATM strategies on Sim (opt-in, Simulator only): nt_atm_templates, nt_atm_status,
    nt_atm_start, nt_atm_close, nt_atm_change — one entry order under a saved ATM template,
    with NinjaTrader arming and managing that template's stop and target. Same gate chain as the
    order module. Full contract: docs/api/atm.md.
  • Strategies on Sim (opt-in): nt_strategy_start adds a strategy to NinjaTrader's own Control
    Center Strategies grid, enabled, on a Simulator/Playback account, so the user sees the row and
    can disable it by hand; nt_strategy_stop disables it and reports the position and working
    orders left behind (it does not flatten); nt_strategy_runs reads state, position, working
    orders and realized P&L for what this server started. Full contract: docs/api/strategyrun.md.
  • Playback control and the replay bench (opt-in): nt_playback_seek, nt_playback_speed and
    nt_playback_run (a bounded run job: from/to/speed, always pauses at the end) drive the Market
    Replay clock, gated by the same orders.enabled file, a Connected Playback connection, no
    exposure on any non-Playback account, and no modal dialog. Proven: 3 replay hours in 55 s at
    200x with a strategy running on Playback101, 19 fills collected. Full contract:
    docs/api/playback.md.
  • nt_reconcile: pairs a backtest's trades with a Market Replay run's real fills and reports
    matched pairs (with price/time deltas), fills only on one side, and a plain verdict. A backtest
    stamps a trade at the bar's close time and a replay fill at the real time, so up to one bar of
    time difference is normal (tolerance_seconds); a large price difference points at the
    historical and replay stores holding different data for that day, not a fill-model bug. Full
    contract: docs/api/reconcile.md.
  • Chart control: nt_chart_indicator_add / nt_chart_indicator_remove add or remove an
    indicator on a chart (remove of one this module did not add needs force); nt_chart_set_series
    changes a chart's instrument and/or bar period (refused with an enabled strategy attached);
    nt_chart_scroll_to moves the visible window to a time; nt_trade_shot scrolls to a trade's
    entry and screenshots it. None of these touch an account or need an arming file. Full contract:
    docs/api/chartcontrol.md.

Changed

  • 79 tools (57 + 22).
  • README/API.md: the order module's summary no longer says "it changes and cancels only the
    orders it placed itself" — it can now manage any working order on a Simulator/Playback account,
    and the caps/ceilings numbers are updated to 10/20/60 and 100/100/600.
  • docs/api/playback.md "Status": seek, speed and the run driver are exercised on NinjaTrader
    8.1.8.2 (see Added, above).
  • docs/api/chartcontrol.md "Status": indicator add/remove and scroll are exercised on NinjaTrader
    8.1.8.2. A series change can be undone exactly with restore.

Fixed

  • A single-series backtest with High fill resolution ended as error in 1.3.1 although the run
    had happened: the check after the run counted the fill series NinjaTrader adds for High as a
    second data series. Multi-series + High is now refused BEFORE the run, on a throwaway instance
    that counts only the series the strategy itself adds, so NinjaTrader never shows its dialog;
    single-series + High runs.

  • Every dry run on a Playback account says when the replay is paused (replayWarning): nothing
    fills there until the replay clock moves.

  • Rollover warning on backtests. A backtest of a dated futures contract whose window starts
    before that contract became the front month now carries a rollover: warning with the date.
    Observed with a broker data feed: the minute history stored for the December contract on a day
    before the rollover held the same prices as the September contract's, a calendar spread away
    from the December prices a Market Replay recording of that day held.

  • The "connect a data provider" warning compared times and not dates, so it fired on every full
    day (a session ends before midnight). It now fires only when whole days are missing.

Known limitations

  • An order that was created but never sent (for example after a failed ATM start on a build
    before this one) stays in NinjaTrader's account as Initialized / CancelPending until
    NinjaTrader restarts. The exposure guards count it as a working order on purpose; restart
    NinjaTrader to clear it.
  • nt_chart_set_series(restore=True) forgets the original series after a NinjaScript reload.
  • A resting bracket's exits do not survive a NinjaScript reload: the bracket watcher is a static
    that a hot reload discards, so a resting entry submitted before a reload gets no exits.
  • A part-filled resting entry is protected only once it reaches a terminal state (Filled,
    Cancelled or Rejected); one that part-fills and keeps resting is not protected until then.
  • Strategies started by nt_strategy_start are not re-adopted by id after a NinjaScript reload:
    they keep running and keep their Control Center grid row, but nt_strategy_stop can no longer
    reach them by the id this server returned — disable them by hand in the grid instead.

nt8-mcp 1.3.1

Choose a tag to compare

@tbraman-dev tbraman-dev released this 20 Sep 02:31

Fixed

  • A backtest that never ran can no longer report done. A strategy that never started, no
    bars loaded, or a multi-series strategy asked for High fill resolution ends as state:"error"
    with the reason (NinjaTrader's own dialog text when there is one). A continuous-contract name
    is refused with a 400 before the job is queued.
  • Backtest output now holds the lines the run printed (read from the output ring by cursor);
    null plus outputNote when they could not be captured, never a false [].
  • sharpe and profitFactor are null on fewer than two trades.
  • nt_optimize and nt_walkforward model costs: slippage_ticks, commission_template,
    include_commission, fill_resolution*, fill_limit_on_touch go to every inner backtest and
    are echoed in costs. A failed inner run is an error row, never a zero-profit result.
  • nt_data_download works on a broker data feed. The historical fetch now uses the bars
    request a backtest makes (merge policy DoNotMerge); the earlier request returned no bars.
    A failure names the route it used.

Added

  • equity on every backtest: cumulative net profit per closed trade, by exit time.
  • nt_walkforward / nt_optimize: include_trades=False by default and a compact per-window
    table; the response schema is in docs/api/optimize.md.
  • nt_analyze: breakdowns by month (exit time), weekday, hour, side, MAE / MFE, streaks,
    drawdown with start / trough / recovery, time under water.
  • Run registry: every finished nt_backtest is saved with its request, costs, data window and a
    hash of the strategy source. nt_runs, nt_run, nt_run_compare.
  • nt_api_search / nt_api: real NinjaScript signatures by reflection on the loaded assemblies.
  • nt_data_probe: how far back the connected provider serves an instrument.
  • nt_data_coverage reports NinjaTrader's bars cache for the instrument's contract chain.
  • nt_status adds an out-of-band check from Python (disk dates and installed files against the
    repo), so a stale AddOn cannot vouch for itself.

Changed

  • /data/download needs no arming file any more (a download moves no money). It is still
    refused without a real data provider connected and while any account has a position or a
    working order. 57 tools (50 + 7).

nt8-mcp 1.3.0

Choose a tag to compare

@tbraman-dev tbraman-dev released this 19 Sep 22:08

Added

  • Order entry on Simulator and Playback accounts only, as its own opt-in module
    (addon/NT8BridgeOrders.cs), disarmed by default: GET /orders/status, POST /orders/submit,
    POST /orders/change, POST /orders/cancel, and the tools nt_order_submit, nt_order_change,
    nt_order_cancel. Market, Limit, StopMarket and StopLimit; one account, one instrument, one
    order per call. Full contract: docs/api/orders.md.
  • Its gates: the arming file orders.enabled (24 h, separate from ops.enabled in both
    directions); accounts judged by provider, never by name, with the Backtest account refused;
    refused while any order-routing connection to a real broker is up; dry run, then a signed,
    single-use, 30-second confirm over the exact plan; caps of 2 contracts per order, 5 working
    orders per account and 6 orders per minute, adjustable through nt8mcp\orders.config.json up to
    the code ceilings 10 / 20 / 30; change and cancel only for orders the module placed; an audit
    line for every armed call in nt8mcp\orders.jsonl, written before a confirmed action runs.
  • There is no live-account switch in the order module: it never reads ops.live.
  • scripts/smoke.d/91-orders.sh: disarmed-state checks only; it never arms and never submits.

Changed

  • README: "Why there is no order entry (yet)" is now "Order entry: Simulator only, off by
    default". 50 tools (47 + 3).

Known limitations

  • A NinjaScript reload clears the orders-per-minute count. The other two caps read live state.
  • No brackets, ATM strategies or OCO orders.

v1.2.0: compile loop, chart eyes, headless backtests

Choose a tag to compare

@tbraman-dev tbraman-dev released this 19 Sep 09:21

nt8-mcp 1.2.0

Give your AI assistant eyes and a build loop on NinjaTrader 8. An MCP server (47 tools) plus a
small AddOn that runs inside NinjaTrader. Built for developing indicators and strategies, not for
placing trades. Read-only by default.

First public release of the full toolset; earlier versions were internal.

Highlights

  • Compile without the Editor. nt_check compiles your files offline against your real Custom
    project, so a broken draft never unloads your indicators. nt_compile then builds through
    NinjaTrader's own compiler with no Editor window open and returns file, line, column, code and
    message for every error. nt_reload_assembly loads the new code right away.
  • See the chart as data. Indicator inputs and plot values for the last n bars, drawing objects
    with anchors, bars, and screenshots that never steal focus.
  • Read what your code printed. Print() output and NinjaTrader's log as event rings: no Output
    window needed, a cursor so nothing is read twice, and they still answer when the UI is blocked.
  • Headless backtests. Trades and metrics with no Strategy Analyzer window. Tick Replay, custom
    bar types, slippage, commission templates, saved strategy templates. Every result reports the
    bars that were really loaded (barsFrom, barsTo, warnings).
  • Optimize, walk-forward, PDF report on the same backtest engine, with a hard cap on combinations.
  • Know your data. Local data coverage by day, feed health, connection drop reasons, and an
    offline .nrd Market Replay to Parquet decoder.
  • Executions and performance for any account, with correct pairing across multi-day positions.
  • Self-checks. nt_health, nt_status, nt_compat: which build is running, is it older than
    your source, and what a NinjaTrader update broke.
  • nt8 command line. Every tool is also a shell command: nt8 health.

Safety

No order entry in this version, on purpose. The tool feeds an assistant a lot of text nobody vetted
(output, logs, third-party add-ons), and it runs inside the NinjaTrader desktop with access to every
account. The README explains the reasoning and the plan: Simulator-only order entry as a separate
opt-in module.

The one account-changing feature, the ops module (flatten, naked-position watchdog, reconnect,
restart), is off until you create an arming file by hand. Armed, it works on Simulator accounts only,
shows a dry run first, needs a signed confirm string within 30 seconds, and writes an audit log.

Install

powershell -ExecutionPolicy Bypass -File scripts\install-addon.ps1
cd server && pip install -e .
nt8 health

Requires Windows, NinjaTrader 8 (tested on 8.1.8.2) and Python 3.10+. The .NET SDK is needed for
nt_check only. Details in the README.

Known limitations

  • No order entry (see above).
  • Playback is read-only: no seek or speed control.
  • No Strategy Analyzer automation.
  • A connected Playback connection caps historical data at the replay clock. Backtest results say so
    in warnings.

Portions adapted from eman007/cli-nt-bridge (MIT). See NOTICE.
Not affiliated with NinjaTrader, LLC.

Full details: CHANGELOG.md · API.md