NinjaTrader is one of the most popular platforms for futures and forex traders, and for good reason — fast execution, solid charting, and a real programming environment under the hood. But NinjaScript development has a learning curve that catches a lot of traders (and frankly, a lot of developers) off guard.
If you’re thinking about hiring someone to build a custom indicator or strategy, here’s what you need to know first.
What NinjaScript Actually Is
NinjaScript is C# with a framework layer on top. That’s important to understand. It’s not a toy scripting language like some platforms offer. It’s full .NET, which means a competent C# developer can do serious work — custom UI panels, multi-threaded data processing, external API calls, database integration.
But — and this is a big but — NinjaTrader‘s framework imposes a specific lifecycle model. You don’t just write procedural code that runs top to bottom. Your strategy responds to events: bars closing, orders filling, connections changing, state transitions. If a developer doesn’t respect this model, the strategy will work on historical data and blow up in real-time.
The State Management Problem
This is the single biggest source of bugs in NinjaScript strategies. Here’s what proper state handling looks like in `OnStateChange`:
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "Mean reversion strategy with volatility filter";
Name = "MRVol";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 1;
IsOverlay = false;
}
else if (State == State.Configure)
{
// Add secondary data series HERE, not in SetDefaults
AddDataSeries(BarsPeriodType.Minute, 60);
}
else if (State == State.DataLoaded)
{
// Initialize indicators AFTER data is loaded
atr = ATR(BarsArray[0], 14);
smaFast = SMA(BarsArray[0], 20);
smaSlow = SMA(BarsArray[1], 50); // 60-min SMA
}
}
protected override void OnBarUpdate()
{
// CRITICAL: check which BarsInProgress is calling
if (BarsInProgress != 0)
return;
// Don't process until all series have enough bars
if (CurrentBars[0] < 20 || CurrentBars[1] < 50)
return;
// Now safe to reference both data series
double volatility = atr[0];
double fastMA = smaFast[0];
double slowMA = smaSlow[0]; // 60-min value
// Strategy logic here...
}
See that `BarsInProgress` check? Miss it with multi-timeframe strategies and you’ll get index-out-of-range exceptions that only show up during live trading, not backtesting. I’ve lost count of how many “broken” strategies we’ve been asked to fix where this was the root cause.
The `CurrentBars` check is equally critical. During historical processing, different data series load at different rates. Accessing `smaSlow[0]` before the 60-minute series has 50 bars loaded will either crash or return garbage data silently.
What NinjaScript Can Do Well
What NinjaScript Can’t Do (Easily)
Red Flags When Hiring a NinjaScript Developer
They deliver compiled DLLs instead of source code
This is the biggest one. If a developer hands you a `.dll` file instead of `.cs` source files, walk away. You should own your code — be able to read it, modify it, hire someone else to work on it later. Compiled-only delivery means you’re locked to that developer forever.
At QuantScripts, every NinjaTrader project ships with full source code. It’s your strategy. You should have the keys.
They don’t test on Market Replay
Backtesting on historical bars is a start, not a finish. Market Replay processes tick-by-tick data and exposes timing issues, fill assumptions, and order management bugs that bar-level testing hides. Any serious NinjaScript developer should be testing strategies against replay data before declaring them ready.
They can’t explain the difference between `Calculate.OnBarClose` and `Calculate.OnEachTick`
This isn’t trivia — it fundamentally changes how your strategy behaves in real-time. `OnBarClose` means `OnBarUpdate` fires once per bar. `OnEachTick` means it fires on every incoming tick. A strategy that works beautifully on `OnBarClose` can generate dozens of spurious signals on `OnEachTick` if the logic isn’t written to handle it.
If your strategy needs intra-bar decision making (trailing stops that update tick-by-tick, for example), the developer needs to understand this distinction cold.
They’ve never dealt with `State.Realtime`
There’s a transition that happens when NinjaTrader switches from processing historical data to real-time data. Orders that were submitted during historical processing behave differently than orders submitted in real-time. Position tracking can get confused at the boundary. A developer who’s only tested on backtests and never run a strategy live (or at least on sim in real-time) will miss these edge cases.
What to Look for Instead
Ask for references or examples specific to NinjaTrader. General C# developers can learn NinjaScript, but the framework quirks take time to internalize. Someone who’s built 10 NinjaScript strategies will deliver faster and with fewer bugs than someone who’s built 100 C# applications but never touched NinjaTrader.
Ask how they handle testing. The answer should include backtesting, Market Replay, and real-time sim testing. If they only mention backtesting, they’re going to miss things.
Ask about their state management approach. Even a non-technical trader can ask “how do you handle the transition from historical to real-time data?” and evaluate whether the answer sounds confident and specific or vague and hand-wavy.
Ask about ongoing support. NinjaTrader releases updates that occasionally break things. Your broker might change something. Markets evolve. A good development relationship includes some level of maintenance support.
The Scope Question
Before you reach out to any developer, document your strategy as specifically as you can:
The more specific your spec, the more accurate your quote. “I want a mean reversion strategy” could be a $3,000 project or a $15,000 project depending on what you actually mean.
Getting Started
If you’re looking for experienced NinjaScript development, check out our NinjaTrader development services or book a call to walk through your strategy. We’ll tell you honestly what it’ll take — and if NinjaTrader is even the right platform for what you’re trying to do.
Interested in implementing this strategy? Check out our QuantConnect development services for professional algorithm development.