PitBridge
Join the waitlist

NinjaTrader and AI agents

NinjaTrader 8 ATI: the Automated Trading Interface explained

The NinjaTrader 8 Automated Trading Interface is the platform's supported way in from an outside program: a folder that reads semicolon-delimited OIF text files, and NTDirect.dll for compiled callers. This is the reference on how both work, the OIF filename and incoming-folder gotchas, what the ATI deliberately does not do (no risk checks, Windows-local, and for the file route no order acknowledgements back), and why an in-platform NinjaScript AddOn on the Cbi object model is a different tool for AI-driven automation.

On this page

If you have looked into automating NinjaTrader from outside the platform, you have met the NinjaTrader 8 ATI, the Automated Trading Interface. It is NinjaTrader’s own supported door for an outside program to drive order execution, and it comes in two shapes that trip people up in different ways: a folder that watches for plain text order files, and a DLL you call from compiled code. This is the reference on how each one actually works, the small mechanical details that cause silent failures, and, just as important, what the ATI deliberately does not do. That last part is the whole reason a bridge like PitBridge exists.

What the ATI is, in NinjaTrader’s own words

NinjaTrader’s help guide describes the Automated Trading Interface as a set of “efficient protocols to communicate trading signals from various external sources to NinjaTrader for the automation of order execution” (NinjaTrader ATI help, retrieved 2026-07-13). It is meant for signals coming from charting applications, custom programs written in environments like Visual Studio .NET or Excel, and black box systems. The same page draws a hard boundary that matters more than any feature list: “This interface is ONLY used for processing trade signals generated from external applications and is NOT a full blown brokerage/market data API.”

Hold onto that sentence. The ATI is a signal door, not an account API. It exists so that something outside NinjaTrader can say “buy one” and have NinjaTrader carry it out through your connected broker. It is not a rich, stateful interface to the account, and it was never intended to be one. NinjaTrader frames the whole automation question as two doors: NinjaScript running inside the platform, or an outside program reaching in through the ATI. The broader route map from Python puts the ATI in context next to the other options; this piece stays inside the ATI itself.

The file interface: Order Instruction Files

The file interface is the ATI at its most primitive, and its most language-agnostic. You place a plain text file into a specific folder and NinjaTrader reads it. That is the whole mechanism, and every detail of it is a place to get something subtly wrong.

The file is an Order Instruction File, or OIF. NinjaTrader reads OIFs from the incoming folder inside your NinjaTrader documents directory, so the target is My Documents\<NinjaTrader Folder>\incoming (NinjaTrader OIF help, retrieved 2026-07-13). Fields inside the file are separated by semicolons: “The delimiter required is the semicolon.” And the instruction set is small and blunt, covering the whole lifecycle: PLACE, CHANGE, CANCEL, CLOSEPOSITION, REVERSEPOSITION, CANCELALLORDERS, CLOSESTRATEGY, and the panic command FLATTENEVERYTHING.

incoming/oif1.txt
PLACE;Sim101;MES 09-26;BUY;1;MARKET;;;DAY;;;;;
# semicolon-delimited fields: command, account, instrument, action,
# qty, order type, limit, stop, TIF, then optional oco/id/strategy slots.
# a bare FLATTENEVERYTHING on its own line closes and cancels everything.

Example OIF format, not a live order. The field order mirrors the DLL Command parameters below. Real values are yours to set; this is illustration.

Two mechanical facts cause most of the “why is nothing happening” reports. First, the filename. NinjaTrader reads files “named oif*.txt”, so the name has to start with oif. A file called order1.txt is not an OIF and is silently ignored. NinjaTrader also recommends incrementing to unique names, oif1.txt, oif2.txt, oif3.txt, to avoid file-locking issues. Second, delivery: NinjaTrader warns you to “Move or directly write OIF files to the incoming folder,” because “Copying OIF files to the incoming folder can cause file locking problems.” Get the folder right, get the oif prefix right, write don’t copy, and NinjaTrader “processes them the instant they are written to the hard disk without delay.”

The deeper limitation of the file route is what does not come back. Writing an OIF is fire and forget. The file is a one-shot instruction dropped on disk; the writer gets no structured acknowledgement, no order id, and no fill confirmation back through the file it wrote. To learn what happened, you have to watch NinjaTrader’s own order and position state by other means. For a fixed strategy that just needs to fling entries, that is tolerable. For anything that has to reason about the outcome of its last order, an AI agent above all, it is a real handicap.

The DLL interface: NTDirect.dll

The second form of the ATI is a DLL. NinjaTrader states that “The .net managed DLL Interface functions are contained in NTDirect.dll,” located in the platform’s bin directory at C:\Program Files\NinjaTrader 8\bin\, and shipped under the name NinjaTrader.Client.dll as well (NinjaTrader DLL interface help, retrieved 2026-07-13). Unlike the file route, the DLL gives you functions to call and, importantly, functions that return information.

The workhorse is Command(), described as the “Function for submitting, cancelling and changing orders, positions and strategies.” Its parameters read like the OIF fields made explicit: a command string, account, instrument, action, quantity, order type, limit price, stop price, time in force, an OCO group, an order id, a strategy, and a strategy id. Around it sit query functions that the file interface has no equivalent for: OrderStatus, Filled, MarketPosition, AvgFillPrice, Connected, NewOrderId, and market-data helpers like SubscribeMarketData and Last.

So the DLL route is meaningfully richer than the file route: you can poll whether an order filled, what the average fill price was, and what the current market position is. But it carries its own constraints. It is a managed .NET assembly, so calling it from a non-.NET language means bridging the CLR rather than doing a clean C-style load, and it runs only on the Windows box where NinjaTrader runs. And it shares the file route’s defining gap: nothing it exposes checks an order against a risk rule.

What the ATI can and cannot do

Line the three options up and the shape of the ATI’s role becomes clear. It is real, official, and useful as plumbing. It is also, by design, missing the two things an AI-driven setup needs most: a rich stateful view of the order lifecycle, and any checkpoint that can refuse a bad order.

Propertyati file (oif)ati dll (ntdirect)in-platform ninjascript
how you drive itwrite oif*.txt to a foldercall Command() over managed .NETcompiled C# hosted inside NT8
feedback to the callernone, fire and forgetpoll OrderStatus, Filled, positionlive Account, Order, Execution objects
where it runsthe Windows NT8 boxthe Windows NT8 boxinside the platform
risk checks on the ordernone built innone built inwhatever the AddOn author builds in
official or third partyofficial, supportedofficial, supportedofficial, native

ati file (oif)

how you drive it
write oif*.txt to a folder
feedback to the caller
none, fire and forget
where it runs
the Windows NT8 box
risk checks on the order
none built in
official or third party
official, supported

ati dll (ntdirect)

how you drive it
call Command() over managed .NET
feedback to the caller
poll OrderStatus, Filled, position
where it runs
the Windows NT8 box
risk checks on the order
none built in
official or third party
official, supported

in-platform ninjascript

how you drive it
compiled C# hosted inside NT8
feedback to the caller
live Account, Order, Execution objects
where it runs
inside the platform
risk checks on the order
whatever the AddOn author builds in
official or third party
official, native
The two ATI forms next to the in-platform object model. The ATI is official and blunt; only code running on the Cbi object model gets the rich order lifecycle and a natural place to put a check.

The honest summary is the one NinjaTrader itself gives: the ATI is for “processing trade signals,” not a full brokerage API. It can place, change, cancel, close, reverse, and flatten. It cannot enforce a limit, and over the file interface it cannot even tell you what happened. Those are not bugs; they are the boundary of what a signal door is for.

Why this matters for AI-driven automation

An AI agent with order access is exactly the caller the raw ATI serves worst. A language model produces a distribution of outputs, and the tail of that distribution includes the wrong size, the wrong side, or a duplicate submit on a retry. Point that at an OIF folder and every one of those mistakes is written straight to disk and executed the instant it lands, with no acknowledgement the agent can even read back to notice. The failure classes are specific and mechanical, and the catalog of how trading bots actually fail walks each one; the point here is that the ATI catches none of them.

The missing piece is a checkpoint. Between the thing proposing an order and the account, there has to be something that refuses an order past your limits, deterministically, in code the caller cannot rewrite. The ATI has no such stage, which is the whole argument for risk controls that live outside the model. For a non-coder, the ATI is not even a tool you would drive by hand: it is the plumbing other software uses to reach the platform.

How PitBridge takes a different route

PitBridge does not use ATI files. Its NinjaTrader piece is a NinjaScript AddOn that runs inside NinjaTrader 8 on the NinjaTrader.Cbi object model, working with real Account, Order, and Execution objects. That is the difference the comparison table points at: instead of dropping a fire-and-forget text file, the AddOn submits through the platform’s own account API and receives genuine order acknowledgements, status transitions, and fills as objects it can reason about. Duplicate broker events can be deduplicated by execution id, a timed-out order can be reconciled against broker truth, and the order carries a stable identity through its whole lifecycle, none of which a one-shot OIF gives you.

PitBridge order pathAn order intent travels from the AI agent through the PitBridge daemon to the guardrail engine, which either allows it through to NinjaTrader 8 or blocks it with a stated reason.AI AGENTmcp / rest clientPITBRIDGE DAEMONlocalhost:8873GUARDRAIL ENGINE12 rules activeNINJATRADER 8Sim101ALLOW buy 2 MES. all rules pass.BLOCK buy 10 MES. size 10 > max_contracts_per_order 2.

Example decisions: ALLOW buy 2 MES, all rules pass. BLOCK buy 10 MES, size 10 exceeds max_contracts_per_order 2.

The order route with a real checkpoint: the agent proposes, a deterministic guardrail engine adjudicates, and only an allowed order reaches NinjaTrader 8. The block is shown as plainly as the allow.

In front of the AddOn sits the part the ATI has no equivalent for: a deterministic guardrail engine in the daemon. Every proposed order, whether it comes from an AI agent over MCP or a Python script over localhost REST, passes the same checks before the AddOn is asked to do anything, and an order past your limits comes back as a structured reason code, not an execution.

agent tool calls
place_order account=sim instrument="MES 09-26" side=BUY qty=1   -> SUBMITTED, then FILLED filled_qty=1
place_order account=sim instrument="MES 09-26" side=BUY qty=10  -> BLOCKED reason_code=MAX_CONTRACTS_PER_ORDER

Real tool name and reason code against the local daemon. Fills are synthetic simulation fills, not live results. The block is a value the caller can read, the opposite of a fire-and-forget file drop.

This is not a claim that the ATI is broken. It is a supported, documented interface that does its narrow job. It is a claim that a signal door and a guarded order pipeline are different tools for different problems, and an AI agent belongs behind the second one. What the twelve checks refuse, and in what fixed order, is on the guardrails page, and where every component runs is in the security model.

Honest status: paper by default, live gated

Everything above describing PitBridge runs against paper and simulation accounts today. In the open core mode = "live" is intentionally out of reach: arm-live refuses, because live execution ships separately as a paid, closed component, and there is no agent tool or API route to change that. Live execution has been in production on a funded futures account since 30 July 2026, behind an operator-run arm step. The AddOn is the Windows piece, a C# NinjaScript component that runs next to NinjaTrader, while the daemon and your agent run on macOS, Linux, or Windows.

So: the NinjaTrader 8 ATI is the platform’s official outside door, an OIF file interface and an NTDirect.dll interface, both blunt, both Windows-local, and both without a risk check of their own. If your caller is an AI agent, the raw ATI is the wrong seam, and a NinjaScript AddOn on the Cbi object model behind a deterministic engine is the seam that fits. The NinjaTrader 8 MCP bridge is the front door to that route, and the quickstart is the uvx pitbridge setup. If a guarded local path from your agent to NinjaTrader is what you want, tell us your platform on the waitlist. PitBridge is trading infrastructure, not financial advice: it enforces the limits you configure and does not promise any trading outcome. Futures trading carries a substantial risk of loss.

Read the pillar: NinjaTrader 8 MCP bridge

Questions

What is the NinjaTrader 8 ATI?

The Automated Trading Interface is NinjaTrader's supported way to drive order execution from an outside program. NinjaTrader's own help guide describes it as efficient protocols to communicate trading signals from various external sources to NinjaTrader for the automation of order execution, and states plainly that it is ONLY used for processing trade signals from external applications and is NOT a full blown brokerage or market data API. It comes in two forms: a file interface that reads Order Instruction Files, and a DLL interface. Source: ninjatrader.com ATI help guide, retrieved 2026-07-13.

What is an OIF or Order Instruction File?

An OIF is a plain text file that the ATI file interface reads to place or manage an order. You write it into the incoming folder under My Documents in your NinjaTrader directory, named oif followed by anything and ending in .txt (for example oif1.txt), with fields separated by semicolons. NinjaTrader processes the file the instant it is written to disk. Supported instructions include PLACE, CHANGE, CANCEL, CLOSEPOSITION, REVERSEPOSITION and FLATTENEVERYTHING. Source: ninjatrader.com OIF help guide, retrieved 2026-07-13.

Why is my OIF file being ignored?

The two most common causes are the filename and the folder. The file has to match the oif*.txt pattern, so a name that does not start with oif is silently skipped, and it must land in the incoming folder inside your NinjaTrader documents directory. NinjaTrader also recommends incrementing to unique names such as oif1.txt, oif2.txt to avoid file locking, and writing or moving files into the folder rather than copying them, which can cause locking problems. Source: ninjatrader.com OIF help guide, retrieved 2026-07-13.

What is NTDirect.dll?

NTDirect.dll is the assembly that holds the ATI DLL interface functions, shipped in the NinjaTrader 8 bin directory and also referred to as NinjaTrader.Client.dll. It is a .NET managed DLL, so a caller invokes functions such as Command to submit, cancel or change orders, and query functions such as OrderStatus, Filled, MarketPosition and AvgFillPrice for feedback. Because it is managed .NET rather than a plain C library, calling it from a non-.NET language means bridging the CLR. Source: ninjatrader.com DLL interface help guide, retrieved 2026-07-13.

Does the NinjaTrader ATI check orders for risk?

No. The ATI submits what it is given. There is no position cap, daily loss halt, or rate limit between the OIF or the DLL call and the account, so whatever writes the file or calls the function is fully trusted. If a bug sends a quantity of 100 instead of 1, the ATI forwards it. That missing checkpoint is exactly what a guardrail layer is for, and it is why an unattended AI agent driving the raw ATI is a poor idea.

Can I run an AI trading agent through the ATI?

You can, but the ATI is a blunt tool for it. The file route is fire and forget: writing an OIF gets no structured acknowledgement back to the writer, so an agent cannot cleanly read whether its order filled from the file it wrote. The DLL route exposes status query functions but is Windows-local managed .NET. Neither offers any risk check. An agent with order access fails in specific ways that a raw ATI does nothing to catch, which is why PitBridge puts a deterministic engine in the path instead.

How is PitBridge different from driving the ATI directly?

PitBridge does not use ATI files at all. Its NinjaTrader piece is a NinjaScript AddOn that runs inside NinjaTrader 8 on the Cbi object model, working with real Account, Order and Execution objects, so it gets genuine order acknowledgements and fills rather than fire-and-forget file drops. In front of that sits a deterministic guardrail engine that refuses any order past the limits you configure, before the platform ever sees it. The open core is paper and simulation only, live is gated behind a separate paid component, and no order routes through a PitBridge server.

PitBridge is in development. NinjaTrader 8 is first.

Tell us your platform and we email you when your setup is supported. Nothing else.