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.
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.
| Property | ati file (oif) | ati dll (ntdirect) | in-platform ninjascript |
|---|---|---|---|
| how you drive it | write oif*.txt to a folder | call Command() over managed .NET | compiled C# hosted inside NT8 |
| feedback to the caller | none, fire and forget | poll OrderStatus, Filled, position | live Account, Order, Execution objects |
| where it runs | the Windows NT8 box | the Windows NT8 box | inside the platform |
| risk checks on the order | none built in | none built in | whatever the AddOn author builds in |
| official or third party | official, supported | official, supported | official, 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 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.
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.
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.