CompositeSignal Optimization Guide
1. What CompositeSignal Is
CompositeSignal is a composite entry/exit indicator that only fires a signal when four independent reads on the market agree. It doesn't trade off a single moving-average cross — it checks trend, momentum, and directional bias together, and only then manages a ratcheting stop for the trade it just opened.
The four components:
- Balance Lines (trend). A short-period and a long-period Donchian midpoint
(MAX(High) + MIN(Low)) / 2. When the short balance line is above the long one, the regime is bullish; below, bearish. - LinRegSlopeBounds (momentum). The slope of a linear regression over recent closes, compared against its own rolling mean ± a standard-deviation band. A long candidate needs the slope rising up out of its lower band (recovering from an oversold momentum dip); a short candidate needs it falling out of its upper band.
- Dominant Movement (bias). The ratio of bullish candle-body size to total candle-body size over a lookback window, smoothed with an EMA. Above the bull threshold (default 55) reads bullish; below the bear threshold (default 45) reads bearish.
- Trailing Stop (exits). An ATR- or StdDev-based stop that only exists while a trade is open. It ratchets in your favor every bar and never loosens.
CompositeSignal maintains its own internal trade state (flat / long / short) bar to bar. The trailing stop and exit marker are only computed while that state says you're actually in a trade — this is a deliberate design choice, not an oversight, and it matters (see Section 8).
2. Installation
Manual .cs drop (how this indicator ships). Copy CompositeSignal.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. CompositeSignal has no dependencies beyond NinjaTrader's built-in Indicator base class methods (MAX, MIN, SMA, EMA, StdDev, ATR, LinRegSlope) — copying only the single .cs file is correct and sufficient.
3. Adding It to a Chart
Open a chart, right-click, choose Indicators..., find CompositeSignal in the list, and add it. It draws as an overlay directly on the price panel (balance lines, active stop line, and entry/exit arrows all plot on price).
Warmup. No signal or plot will appear until every component has enough bars: the balance lines need Balance Long Period bars (default 200), the momentum check needs Slope Period + Slope StdDev Period bars (default 54), and the bias check needs Dom Period + Dom Smooth Period bars (default 28). The indicator waits for the slowest of these — in the default configuration, that's the 200-bar balance line. Nothing will plot before bar 200. This is normal.
4. Parameter Reference
All names and defaults below are transcribed directly from the indicator's property definitions, so what you see in the NinjaTrader parameters dialog will match this table exactly.
| Parameter (display name) | Default | Group | What it does / when to change it |
|---|---|---|---|
| Slope Period | 14 | 1. Momentum | Lookback for the LinRegSlope calculation. Shorter reacts faster to momentum shifts; longer smooths it out. |
| Slope StdDev Period | 40 | 1. Momentum | Window used to compute the rolling mean and standard deviation that the slope is compared against. Larger periods produce a more stable band; smaller periods adapt faster to changing momentum regimes. |
| Slope StdDev Mult | 1.0 | 1. Momentum | Width of the band around the slope's rolling mean, in standard deviations. Raise it to require a more extreme momentum reading before a reversion candidate counts; lower it to accept milder reversions. |
| Dom Period | 14 | 2. Bias | Lookback (in bars) over which bullish vs. bearish candle-body size is totaled for the raw dominance ratio. |
| Dom Smooth Period | 14 | 2. Bias | EMA smoothing period applied to the raw dominance ratio. Larger values produce a steadier bias read; smaller values react faster to a shift in candle character. |
| Dom Bull Threshold | 55 | 2. Bias | Smoothed dominance must be above this value for the bias to count as bullish. Raise it to demand stronger bullish candle dominance before allowing a long. |
| Dom Bear Threshold | 45 | 2. Bias | Smoothed dominance must be below this value for the bias to count as bearish. Lower it to demand stronger bearish candle dominance before allowing a short. |
| Balance Short Period | 20 | 3. Trend | Lookback for the short-term Donchian midpoint. |
| Balance Long Period | 200 | 3. Trend | Lookback for the long-term Donchian midpoint. This is the largest warmup requirement in the indicator — nothing plots until this many bars have loaded. |
| Trail Period | 14 | 4. Exits | Lookback for the ATR or StdDev calculation used to size the trailing stop. |
| Trail Multiplier | 2.5 | 4. Exits | Multiplier applied to the ATR/StdDev unit to set stop distance from price. Raise it for a wider stop (fewer whipsaw exits, larger risk per trade); lower it for a tighter stop. |
| Trail Type | Atr | 4. Exits | Atr uses Average True Range as the volatility unit; Std uses standard deviation of price instead. ATR is the more conventional choice for futures scalping. |
| Require Price Above/Below Balance | false | 5. Filters | When true, longs additionally require Close > BalanceShort, and shorts require Close < BalanceShort. Adds a price-location confirmation on top of the trend/momentum/bias agreement. |
| Require Momentum Confirm | false | 5. Filters | When true, longs additionally require Close[0] > Close[1] (the current bar closed higher than the prior one), and shorts require the reverse. A simple last-bar-direction confirmation. |
| Cooldown Bars | 0 | 5. Filters | Minimum bars to wait after an exit before a new entry is allowed. Raise this to avoid re-entering immediately after getting stopped out into a still-choppy market. |
| Enable Time Filter | false | 5. Filters | When true, entries are only allowed within the Session Start–Session End window (chart time). Does not affect exits — an open trade's trailing stop still manages normally outside the window. |
| Session Start Hour / Minute | 9 / 30 | 5. Filters | Start of the entry window when Enable Time Filter is on. Default is 9:30. |
| Session End Hour / Minute | 16 / 0 | 5. Filters | End of the entry window when Enable Time Filter is on. Default is 16:00. Same-day window only — Session Start must be earlier than Session End. |
| Enable Exit Signals | true | 6. Display | Master switch for the trailing-stop exit logic. When off, a trade's internal state never exits on a stop cross, so tradeState — and therefore new entries — can get stuck; see Section 8. |
| Enable Bar Coloring | true | 6. Display | Tints the chart background by trend direction and dominance strength (light/medium/strong tiers). Purely visual — has no effect on signal logic. |
| Enable Balance Lines | true | 6. Display | Shows or hides the Balance Short / Balance Long plot lines. Purely visual — the balance-line trend calculation still runs and still gates signals either way. |
| Arrow Offset Ticks | 3 | 6. Display | Distance, in ticks, that entry/exit arrows are drawn away from the bar's high or low. |
| Bullish Color / Bearish Color / Exit Color | Lime / Red / Yellow | 7. Colors | Colors for long-entry arrows, short-entry arrows, and exit markers respectively. |
5. How a Signal Forms
Signals evaluate on closed bars only (Calculate = OnBarClose). Here is the walk-through for one long entry, followed by its exit:
- On each new closed bar, the indicator first carries forward its trade state, active trailing stop, and cooldown counter from the prior bar.
- It computes all four components: balance-line trend direction, the momentum reversion check, the smoothed dominance bias, and the ATR/StdDev unit for stop sizing. If any component doesn't yet have enough bars, the indicator returns early and does nothing else this bar.
- If the indicator is currently flat (
tradeState == 0), and no exit happened this bar, and the cooldown has elapsed, and (if the time filter is on) the current bar is inside the session window, entries are considered. - A long fires when: the trend is bullish (short balance line above long balance line), the price-location filter passes (if enabled), the momentum slope is rising up out of its lower reversion band, the dominance bias is bullish (above the Bull Threshold), and the momentum-confirm filter passes (if enabled). All of these must be true simultaneously — this is a logical AND across all four components plus any enabled filters.
- A short fires under the mirror-image conditions.
- On entry, the indicator sets its internal state to long or short, seeds an initial trailing stop (
Low - TrailMultiplier * ATRfor longs,High + TrailMultiplier * ATRfor shorts), and draws an up- or down-arrow at the bar's low/high, offset by Arrow Offset Ticks. - On every subsequent bar while in a trade, the stop is recalculated and ratcheted — for a long,
TrailStop = Max(TrailStop, Low - TrailMultiplier * ATR), so it only ever moves up. The active stop line is redrawn each bar in DodgerBlue (long) or OrangeRed (short). - The moment price closes through that stop (
Close < TrailStopfor a long,Close > TrailStopfor a short) — and only if Enable Exit Signals is on — the indicator flips back to flat, resets the trailing stop to zero, resets the cooldown counter, and draws a yellow exit marker. From this point, a new entry can be considered again once the cooldown (if any) has elapsed.
There is no stop-and-reverse behavior here (unlike some trend indicators): CompositeSignal must return to flat via an exit before it will consider a new entry in the opposite direction.
6. Tuning Cookbook
Goal: fewer, stronger signals. Change: raise Dom Bull Threshold / lower Dom Bear Threshold (widen the gap between them), raise Slope StdDev Mult, and/or turn on Require Price Above/Below Balance and Require Momentum Confirm. Expect: fewer entries overall, but each one represents stronger agreement across all four components. Stacking multiple filters compounds — turning on both optional filters at once can cut entry frequency substantially, so add them one at a time and watch the effect before combining.
Goal: catch trend starts earlier. Change: lower Slope Period and Dom Smooth Period so momentum and bias react faster; consider narrowing the Dom Bull/Bear thresholds back toward 50/50. Expect: earlier entries into a developing trend, but more false starts from noise that reverses quickly. This is the core responsiveness/noise trade-off in the indicator.
Goal: reduce whipsaw exits in choppy markets. Change: raise Trail Multiplier (wider stop) and/or raise Cooldown Bars so a stopped-out trade doesn't immediately re-enter into the same chop. Expect: fewer stop-outs per trend, but larger risk per trade from the wider stop, and slower re-entry after a legitimate exit.
Goal: restrict trading to your session. Change: turn on Enable Time Filter and set Session Start/End to your actual trading window. Expect: no new entries outside that window. Remember this only gates entries — a trade opened before the window closes will still be managed (stop still ratchets, exit signal can still fire) even after the session window ends, since the time filter is entry-only.
Goal: scalping vs. a slower, more selective posture. Change: for a tighter scalping feel, keep the defaults (14/40/20/200) on a fast timeframe like 1- or 5-minute. For a more selective, swing-oriented feel, raise Balance Short/Long Period and Slope Period proportionally, and consider a slower timeframe. Expect: the balance-line periods and the timeframe interact — 200 bars means a much longer real-world lookback on a 15-minute chart than on a 1-minute chart. Tune period lengths and timeframe together.
7. Bar Coloring Reference
When Enable Bar Coloring is on, the background tints by trend direction and dominance strength:
| Regime | Condition | Tint |
|---|---|---|
| Strong bullish | Bullish trend, DomSmooth > 70 | Strong green |
| Medium bullish | Bullish trend, DomSmooth > 55 | Medium green |
| Light bullish | Bullish trend, DomSmooth > 50 | Light green |
| Light bearish | Bearish trend, DomSmooth < 50 | Light red |
| Medium bearish | Bearish trend, DomSmooth < 45 | Medium red |
| Strong bearish | Bearish trend, DomSmooth < 30 | Strong red |
Note the bar-coloring bands use fixed values (70/55/50 and 30/45/50) — they are independent of the Dom Bull/Bear Threshold parameters that actually gate entries. Changing Dom Bull/Bear Threshold does not change where the background color bands sit; it only changes when an entry is allowed to fire. This is purely a visual/entry-logic separation, not a bug, but it's easy to assume they're linked — they aren't.
8. Known Limitations & Honest Caveats
- Turning off "Enable Exit Signals" can strand you in a trade indefinitely. With this off, the trailing stop still ratchets and redraws every bar, but the
Closevs.TrailStopcheck that would flip state back to flat never runs. The indicator's internal state stays "long" or "short" until you manually flip charts or the position otherwise resets — and since new entries only fire while flat, no new signal (long or short) can appear until that happens. Leave this on unless you are deliberately managing exits by hand and understand this consequence. - No stop-and-reverse. Unlike some composite trend tools, this indicator will not flip directly from long to short (or vice versa) on a single bar. It must pass through a flat state first. If you're used to stop-and-reverse behavior from another indicator, don't expect it here.
- The optional filters (Section 5, Group 5) are
[Display]-only properties, not[NinjaScriptProperty]. They work normally when you set them through the chart's Parameters dialog. If you ever callCompositeSignal(...)directly from strategy code with explicit arguments, these five filter parameters and the display toggles are not part of that generated method signature — only the core numeric/trend/exit parameters and Arrow Offset Ticks are. This is a minor technical wrinkle, not something that affects normal chart use. - Bar-coloring thresholds are fixed, not parameterized. As noted in Section 7, the 70/55/50/45/30 color bands don't move when you change Dom Bull/Bear Threshold. If you retune the bias thresholds significantly, the background coloring may stop lining up intuitively with when entries actually fire.
- Nothing here is a claim about future performance. Any historical behavior you observe on your own charts is hypothetical/backward-looking and does not guarantee similar results going forward.
9. Troubleshooting
Nothing is plotting at all. You're almost certainly still in warmup — nothing appears before Balance Long Period bars have loaded (200 by default). Load more historical data or wait for more bars to form.
I'm seeing an exit "X" on nearly every candle, and the whole chart background is tinted. This was a real bug in an earlier draft of this indicator that computed the trailing stop unconditionally on every bar instead of only while in a trade. If you see this behavior, you are running the wrong/older copy of CompositeSignal.cs — replace it with the current version described in this guide, which gates all trailing-stop and exit logic behind actual trade state.
No arrows are appearing even though I can see the trend and bias plots moving. All four components must agree simultaneously — check that trend, momentum-reversion, and bias are actually aligned at the same bar. If you've enabled Require Price Above/Below Balance, Require Momentum Confirm, Cooldown Bars, or the time filter, any one of those can silently block an otherwise-valid entry. Try disabling the optional filters one at a time to isolate which one (if any) is holding back a signal.
I turned off Enable Exit Signals and now no new entries ever fire. This is expected — see the caveat in Section 8. Turn Enable Exit Signals back on, or manually intervene to reset state (e.g., remove and re-add the indicator to force a fresh calculation).
The indicator shows as disabled after I edited the source. After any change to the .cs file, recompile: open the NinjaScript Editor and press F5. NinjaTrader disables indicators whose compiled code is out of sync with the source until a successful recompile.
10. Risk Disclaimer
Trading futures and other derivatives involves substantial risk of loss and is not suitable for every investor. CompositeSignal is an educational and analytical tool, not a signal service or investment advice. Any historical or hypothetical performance referenced in connection with this indicator does not guarantee future results. You are solely responsible for your own trading decisions, risk management, and compliance with applicable rules. Past performance, backtested results, and hypothetical scenarios have inherent limitations and should not be relied upon as an indicator of future performance.