EnhancedORBIndicator Optimization Guide
1. What EnhancedORBIndicator Is
EnhancedORBIndicator is a visualization-only companion to the Enhanced ORB Strategy (OpeningRangeBreakoutEnhanced in EnhancedORBStrategy.cs). It draws everything the strategy would act on — or reject — without ever placing an order: the opening range box, the OR high/low lines, a shaded trade window, and a marker at every breakout crossing showing whether that breakout would have passed the strategy's entry filters. Nothing here submits orders, touches Position, or reads account state; it is a pure charting tool that never appears in the Strategies tab, only as an indicator you drop on a chart.
It reuses the existing OpeningRangeIndicator internally for the opening-range high/low calculation, via orIndicator = OpeningRangeIndicator(OrStartTime, OrEndTime); in State.DataLoaded. That means the OR high/low you see on this indicator is computed by the exact same code path the strategy itself uses — one shared source of truth, not a reimplementation that could quietly drift out of sync.
Because the Opening Range group and Entry Filters group use the same parameter names and defaults as Enhanced ORB Strategy, you can copy your strategy instance's settings straight into this indicator and watch, on a chart, exactly which crossings that configuration would have taken and which it would have rejected — before committing to a live or simulated run.
2. Installation
Manual .cs drop (how this indicator ships)
Copy EnhancedORBIndicator.cs into your bin\Custom\Indicators folder, then open the NinjaScript Editor inside NinjaTrader and press F5 to compile. If compilation fails, read the error list at the bottom of the editor.
Warning: Never unzip a NinjaScript export .zip manually into bin\Custom. Exported .zip packages from the NinjaScript editor can bundle unrelated files — including stale copies of NinjaTrader's own stock indicators — alongside the file you actually want. Hand-extracting one of these zips risks silently overwriting live stock indicator files with older versions. Copying only the single .cs file (plus making sure OpeningRangeIndicator.cs is already present in your Indicators folder, since EnhancedORBIndicator calls it internally) is correct and sufficient.
3. Adding It to a Chart
Open a chart, right-click, choose Indicators..., find EnhancedORBIndicator in the list, and add it. It draws as an overlay directly on the price panel (IsOverlay = true, DrawOnPricePanel = true) — the OR box, OR lines, breakout arrows, rejection labels, and trade-window shading all plot on price, alongside your candles.
Warmup — two floors, not one
- The Opening Range must complete for the current day first. No box, lines, arrows, labels, or shading will appear until the configured OR period (
OrStartTimetoOrEndTime) has actually finished on the chart's current trading day. UntilTimes[0][0].TimeOfDay >= OrEndTime.TimeOfDay, the indicator has no OR high/low to draw or evaluate against. This resets every day — each new session starts back in this same "waiting for OR to complete" state (orPeriodCompleteis reset wheneverTimes[0][0].Datechanges). This is expected daily warmup behavior, not a bug. - A fixed
CurrentBar < 20bar-count floor underneath that. At the very top ofOnBarUpdate(), the indicator returns immediately ifCurrentBar < 20, regardless of what the OR times are set to. On most intraday charts this floor is irrelevant (the OR period itself typically takes far more than 20 bars to complete), but it's worth knowing it's there as a hard secondary gate.
If you don't see anything on a freshly added chart, first check the clock — if it's before OrEndTime for today, that's exactly what's expected.
4. Parameter Reference
The table below is transcribed directly from the [Display] attributes in EnhancedORBIndicator.cs, so what you see in the NinjaTrader parameters dialog will match this table exactly — names, defaults, groups, and descriptions.
| Parameter (display name) | Default | Group | Description |
|---|---|---|---|
| OR Start Time | 09:30 | 1. Opening Range | Opening Range start time |
| OR End Time | 10:00 | 1. Opening Range | Opening Range end time |
| Trade Start Time | 10:00 | 1. Opening Range | Time to start considering breakout signals |
| Trade End Time | 15:45 | 1. Opening Range | Time to stop considering breakout signals |
| Use Minimum Breakout Size | true | 2. Entry Filters | Require minimum breakout distance |
| Minimum Breakout (Ticks) | 5 | 2. Entry Filters | Minimum ticks beyond OR level |
| Use Volume Filter | true | 2. Entry Filters | Require above-average volume |
| Volume Multiplier | 1.2 | 2. Entry Filters | Multiple of 20-period average volume |
| Show OR Box | true | 3. Visual Settings | Draw a shaded box for the opening range |
| OR Box Opacity | 20 | 3. Visual Settings | Opacity of the OR box (1-100) |
| Show OR Lines | true | 3. Visual Settings | Draw horizontal lines at OR high/low |
| OR Line Width | 2 | 3. Visual Settings | Width of OR lines |
| OR Box Color | Orange | 3. Visual Settings | Color of the opening range box |
| OR Line Color | Orange | 3. Visual Settings | Color of the opening range lines |
| Show Breakout Arrows | true | 3. Visual Settings | Draw arrows for breakouts that pass all filters |
| Show Filter Labels | true | 3. Visual Settings | Draw a gray label explaining why a breakout was rejected |
| Show Trade Window Shading | true | 3. Visual Settings | Tint the background during the trade window |
Notes on a couple of entries above:
- Minimum Breakout (Ticks) is range-limited to 1–100 in the source (
[Range(1, 100)]). - Volume Multiplier is range-limited to 0.1–5.0 (
[Range(0.1, 5.0)]). - OR Box Opacity is range-limited to 1–100 (
[Range(1, 100)]). - OR Line Width is range-limited to 1–5 (
[Range(1, 5)]). - OR Box Color and OR Line Color are the color-picker properties (
ORBoxColorSerialized/ORLineColorSerializedin code); both default to Orange.
This is deliberately the same 4 + 4 (Opening Range / Entry Filters) parameter set, with the same names and defaults, as Enhanced ORB Strategy's own Opening Range and Entry Filters groups — that parity is what makes a strategy-configuration preview possible (see Section 6). The indicator's third group, Visual Settings, has no strategy counterpart — it exists purely to control what this indicator draws.
5. How a Signal Forms
Everything below happens inside OnBarUpdate() and its helper EvaluateAndDraw(), on closed bars only (Calculate = Calculate.OnBarClose):
-
The Opening Range is tracked via the internal
OpeningRangeIndicatorinstance. Every bar, the indicator readsorIndicator.ORHighLine[0]andorIndicator.ORLowLine[0]— the same OR high/low values the strategy itself would compute. -
At
OrEndTime, the OR box and lines are drawn (once per day, if enabled). The instantTimes[0][0].TimeOfDay >= OrEndTime.TimeOfDaybecomes true for the first time that day,orPeriodCompleteflips totrue, and — ifShowORBoxis on and both OR levels are valid (> 0) — a shaded rectangle is drawn from the OR start bar to the OR high/low. IfShowORLinesis on, two horizontal lines are drawn at the OR high and OR low, extending out toTradeEndTime. -
Trade-window background shading appears between
TradeStartTimeandTradeEndTime(if enabled). On every bar whereTimes[0][0].TimeOfDayfalls inside that window, ifShowTradeWindowShadingis on, the bar's background is tinted with a light blue shade (BackBrush = sessionShadeBrush). -
A
CrossAbove/CrossBelowof the OR high/low is evaluated — but only once the OR period is complete AND the bar is inside the trade window. The indicator checksCrossAbove(Close, orHigh, 1)for a long candidate andCrossBelow(Close, orLow, 1)for a short candidate, but only after confirmingorPeriodCompleteis true, the bar's time is within[TradeStartTime, TradeEndTime], and both OR levels are valid. Outside the OR-complete/trade-window conditions, the indicator returns early and evaluates nothing. -
The crossing is checked against the minimum-breakout-size filter first (if enabled), then the volume filter (if enabled). Inside
EvaluateAndDraw(): ifUseMinimumBreakoutSizeis on, the breakout distance in ticks is measured ((Close[0] - orLevel) / TickSizefor longs, mirrored for shorts) and compared againstMinimumBreakoutTicks. Only if that filter passes (or is disabled) does the volume filter run: ifUseVolumeFilteris on,Volume[0]is compared againstSMA(Volume, 20)[0] * VolumeMultiplier. The volume filter is skipped entirely if the breakout-size filter already failed. -
If all enabled filters pass, a solid colored arrow is drawn. A long that clears all filters gets a solid Lime up-arrow (
Draw.ArrowUp) below the bar's low; a short gets a solid Red down-arrow (Draw.ArrowDown) above the bar's high. This only happens ifShowBreakoutArrowsis also on — if it's off, a passed breakout draws nothing at all. -
If a filter rejects the breakout, a dimmed gray text label is drawn instead — with the specific rejection reason spelled out. The label uses the exact rejection reason generated in code:
- Breakout-size rejection:
"Breakout too small ({0:0.#} ticks, need {1})"— e.g. "Breakout too small (3.2 ticks, need 5)". - Volume rejection:
"Low volume ({0:0} vs {1:0} avg required)"— e.g. "Low volume (842 vs 1010 avg required)".
The full label text is prefixed with
"X (long) "or"X (short) "depending on direction, so a real label reads like "X (long) Breakout too small (3.2 ticks, need 5)". This only draws ifShowFilterLabelsis on. - Breakout-size rejection:
Show Breakout Arrows and Show Filter Labels are independent toggles, confirmed directly in the code. EvaluateAndDraw() branches on passedFilters: the passed-filter branch checks only ShowBreakoutArrows before drawing an arrow (and returns without drawing anything if it's off), while the separate rejected branch checks only ShowFilterLabels before drawing a label. Neither toggle reads or affects the other — turning one off has zero effect on whether the other still draws.
6. Tuning Cookbook
Goal: preview a specific Enhanced ORB Strategy configuration. Change: set every parameter on this indicator — OR Start/End Time, Trade Start/End Time, Use Minimum Breakout Size, Minimum Breakout Ticks, Use Volume Filter, Volume Multiplier — to match your strategy instance's configuration exactly, field for field. Expect: the arrows and labels on the chart now preview precisely what that strategy configuration would do at each breakout — a solid arrow means the strategy would enter there, and a rejection label tells you exactly which filter (and by how much) would have blocked it.
Goal: reduce visual clutter. Change: turn off Show Filter Labels to see only accepted breakouts (arrows only, no rejection text cluttering the chart), or turn off Show Trade Window Shading if you find the background tint distracting. Expect: a visually quieter chart. Turning off Show Filter Labels does not hide arrows (see Section 5's toggle-independence note), and turning off shading has no effect on OR box/lines/arrows/labels — it only removes the background tint.
Goal: see every breakout regardless of filters.
Change: turn off both Use Minimum Breakout Size and Use Volume Filter.
Expect: every CrossAbove/CrossBelow of the OR high/low inside the trade window now passes EvaluateAndDraw() with passedFilters staying true throughout, so every raw crossing draws as a solid arrow instead of being evaluated against either filter. Useful for seeing the raw, unfiltered breakout frequency before you decide how aggressively to filter it.
Goal: focus purely on the OR levels and window, without any signal markers. Change: turn off Show Breakout Arrows and Show Filter Labels, but leave Show OR Box, Show OR Lines, and Show Trade Window Shading on. Expect: a clean chart showing only the opening range and the trade window — no arrows or text at all, regardless of how many crossings occur or how they'd be filtered.
7. Known Limitations & Honest Caveats
- The
CurrentBar < 20warmup guard is a fixed floor, not adaptive to your configured OR window. This check is literally the first line ofOnBarUpdate():if (CurrentBar < 20) return;. It does not scale with how long your OR period is configured to run — if you set a very short OR window on a very slow timeframe, this fixed 20-bar floor (not the OR-completion check) could in principle be the more restrictive gate in edge cases, though on typical intraday setups the OR-completion wait in Section 3 will dominate. - Parameters are configured independently on the indicator and the strategy — they are not linked.
EnhancedORBIndicatorandOpeningRangeBreakoutEnhanced(the strategy) are separate NinjaScript objects, each with its own copy ofOrStartTime,OrEndTime,TradeStartTime,TradeEndTime,UseMinimumBreakoutSize,MinimumBreakoutTicks,UseVolumeFilter, andVolumeMultiplier. Editing the strategy's settings does nothing to this indicator's settings, and vice versa. If you change your strategy's configuration, you must manually update the indicator's parameters to match if you want the chart preview to stay an accurate reflection of what the strategy would do. - This indicator has no concept of an open position. It cannot preview stop-loss, profit-target, breakeven-trigger, or trailing-stop behavior — none of that logic exists in this file at all (no
Positionaccess, noSetStopLoss/SetProfitTarget/SetTrailStopcalls). It only marks entry-side breakout signals and their filter outcomes. To see how a trade would actually be managed once open — stop placement, breakeven, trailing — you need to run the Enhanced ORB Strategy itself, in simulation or live, through NT8's Strategy Analyzer or a live/sim account.
8. Troubleshooting
I don't see the OR box or lines. Check that Show OR Box / Show OR Lines are actually turned on in the parameters dialog. If they are, confirm OrEndTime has actually been reached yet today on the chart — the box and lines are only drawn once, at the moment the OR period completes for the current day (Section 3). Before that moment each day, there is nothing to draw.
No arrows or labels appear at all. Two independent conditions must both be true before any evaluation happens: the current bar's time must fall inside the Trade Start Time–Trade End Time window, and the OR period must already be complete for the day. If either isn't true yet, OnBarUpdate() returns before ever checking for a crossing — this is normal, not a malfunction. Also double-check Show Breakout Arrows and/or Show Filter Labels aren't both switched off, since a passing or failing breakout will silently draw nothing if its corresponding toggle is off.
The strategy took a trade but the indicator didn't mark it (or vice versa). Since the indicator and strategy are configured completely independently (Section 7), the most common cause is a parameter mismatch — different OR times, different trade window, different filter settings, or a different Minimum Breakout Ticks / Volume Multiplier value between the two instances. Re-check every parameter in Section 4 side-by-side against your strategy's actual settings.
The indicator shows as disabled after I edited the source. Recompile: open the NinjaScript Editor and press F5. NinjaTrader disables any NinjaScript object whose compiled binary is out of sync with its source until a successful recompile completes.
9. Risk Disclaimer
Trading futures and other derivatives involves substantial risk of loss and is not suitable for every investor. EnhancedORBIndicator is an educational and analytical tool, not a signal service or investment advice. Any historical or hypothetical performance referenced in connection with this indicator or its companion strategy does not guarantee future results. Backtested and hypothetical results have inherent limitations and should not be relied upon as an indicator of actual future performance. You are solely responsible for your own trading decisions, risk management, and compliance with applicable rules and regulations.