Releases: tbraman-dev/nt8-mcp
Release list
nt8-mcp 1.5.0
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_statusreads 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_enableand
nt_desk_recover(re-enable allowlisted legs, one row per leg). Alsont_leg_decisions,
nt_crash_reportandnt_lock. Grid rows and order rows now carry strategy and owner ids. nt_lint. A static scan of NinjaScript.csfiles 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, syncDispatcher.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_starttakesbreak_at_eod(defaulttrue, like a
chartless backtest) andtrading_hours, so a live run builds the same bars as its backtest.
nt_backtesttakesbreak_at_eodtoo. A started run survives a NinjaScript recompile. - Changed.
orders.enabledno 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/flattenflattens a Sim/Playback account whatever connection is up. - Fixes. A strategy start is no longer reported as failed while it runs.
realtimeTrades
agrees withrealizedPnL. 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_enableneeds an allowlist file.
Upgrade
- Copy the new AddOn files into NinjaTrader:
powershell -ExecutionPolicy Bypass -File scripts\install-addon.ps1(it also adds the newNT8BridgeDesk.cs), then compile (F5 in the
NinjaScript Editor, ornt8 nt_compile). - Reinstall the server:
pip install -e server. - Restart your MCP client so it loads the new tools.
- Check:
nt8 healthreportsaddonVersion1.5.0.
Known limitations
nt_grid_enablere-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_matchcompares exit prices as given: a reference that records a time exit at a different
bar will differ.nt_lintis a pattern scan: it can miss a hazard and can raise a false alarm.
nt8-mcp 1.4.0
Added
- Order module: brackets, close, reverse, and manage-any-order.
nt_order_bracketsends 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_closeandnt_position_reverse
cancel one instrument's working orders on one account, then flatten it (reversealso enters
the same quantity the other way).nt_order_changeandnt_order_cancelnow 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_startadds 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_stopdisables it and reports the position and working
orders left behind (it does not flatten);nt_strategy_runsreads 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_speedand
nt_playback_run(a bounded run job: from/to/speed, always pauses at the end) drive the Market
Replay clock, gated by the sameorders.enabledfile, 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_removeadd or remove an
indicator on a chart (remove of one this module did not add needsforce);nt_chart_set_series
changes a chart's instrument and/or bar period (refused with an enabled strategy attached);
nt_chart_scroll_tomoves the visible window to a time;nt_trade_shotscrolls 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 withrestore.
Fixed
-
A single-series backtest with High fill resolution ended as
errorin 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 arollover: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 asInitialized/CancelPendinguntil
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,
CancelledorRejected); one that part-fills and keeps resting is not protected until then. - Strategies started by
nt_strategy_startare not re-adopted by id after a NinjaScript reload:
they keep running and keep their Control Center grid row, butnt_strategy_stopcan no longer
reach them by the id this server returned — disable them by hand in the grid instead.
nt8-mcp 1.3.1
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 asstate:"error"
with the reason (NinjaTrader's own dialog text when there is one). A continuous-contract name
is refused with a400before the job is queued. - Backtest
outputnow holds the lines the run printed (read from the output ring by cursor);
nullplusoutputNotewhen they could not be captured, never a false[]. sharpeandprofitFactorarenullon fewer than two trades.nt_optimizeandnt_walkforwardmodel costs:slippage_ticks,commission_template,
include_commission,fill_resolution*,fill_limit_on_touchgo to every inner backtest and
are echoed incosts. A failed inner run is an error row, never a zero-profit result.nt_data_downloadworks on a broker data feed. The historical fetch now uses the bars
request a backtest makes (merge policyDoNotMerge); the earlier request returned no bars.
A failure names the route it used.
Added
equityon every backtest: cumulative net profit per closed trade, by exit time.nt_walkforward/nt_optimize:include_trades=Falseby default and a compact per-window
table; the response schema is indocs/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_backtestis 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_coveragereports NinjaTrader's bars cache for the instrument's contract chain.nt_statusadds 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/downloadneeds 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
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 toolsnt_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 fromops.enabledin 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 throughnt8mcp\orders.config.jsonup to
the code ceilings 10 / 20 / 30; change and cancel only for orders the module placed; an audit
line for every armed call innt8mcp\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
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_checkcompiles your files offline against your real Custom
project, so a broken draft never unloads your indicators.nt_compilethen builds through
NinjaTrader's own compiler with no Editor window open and returns file, line, column, code and
message for every error.nt_reload_assemblyloads 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.nrdMarket 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. nt8command 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
inwarnings.
Portions adapted from eman007/cli-nt-bridge (MIT). See NOTICE.
Not affiliated with NinjaTrader, LLC.
Full details: CHANGELOG.md · API.md