TradingView Dynamic Median Momentum Oscillator [AlgoAlpha] Conversion to NinjaTrader 8
Most momentum oscillators take the difference of price from a moving average. AlgoAlpha’s Dynamic Median Momentum Oscillator takes the difference from a rolling median instead. The median is robust to outliers — a single spike bar can drag a moving average for many bars after, but barely moves a median. So the resulting oscillator is naturally cleaner around news spikes and gaps.
Optional standardization divides the (close − basis) raw oscillator by the average candle range — EMA(High − Low) — so values land on a fixed scale across assets. The ±200 / ±250 / ±300 OB/OS bands work the same on a $5 stock as on a $5,000 futures contract. Smooth MCD = EMA of the standardized oscillator; Signal = EMA of Smooth MCD; histogram = Smooth MCD − Signal.
This post is the NinjaTrader 8 conversion. The full source compiles standalone in indTradingView/, exposes the Smooth MCD, Signal, Histogram, and Super Slow lines as Series<double> outputs for strategy use, and is yours to download as a NinjaScript Archive.
Original Pine Script: Dynamic Median Momentum Oscillator by AlgoAlpha
License: Mozilla Public License 2.0 (MPL 2.0)
🆚 What Makes Dynamic Median Momentum Oscillator Different
Standard MACD takes EMA(close, fast) − EMA(close, slow). Both EMAs lag, both get pushed around by spikes. Dynamic Median Momentum’s basis is a rolling median of HLC3 — the median doesn’t shift on a single spike, only on a sustained shift in the bulk of the distribution. So the basis sits more naturally in the middle of price during a regime, and momentum readings reflect actual deviation rather than EMA lag.
Optional standardization for asset-agnostic OB/OS. Without standardization, (close − basis) scales with price — different ranges for different assets. The Standardize toggle divides by EMA(High − Low) so the oscillator is in ‘average-candle-range’ units. The ±200 / ±250 / ±300 bands then work universally.
Four display modes. All shows everything. Fast hides the slow lines and shows only the histogram. Slow shows only the Smooth MCD + Signal lines. Super Slow renders Smooth MCD as a colored line filled to zero with bull / bear strength shading — the cleanest ‘is the trend healthy?’ view.
State-driven histogram coloring. Histogram bars are colored darker when extending (the absolute value is growing) and lighter when fading (the absolute value is shrinking). So ‘momentum building’ versus ‘momentum exhausting’ is on the bars themselves.
⚙️ Settings
Dynamic Median Momentum Oscillator exposes its inputs in three property groups: the calculation parameters (basis, smoothing, signal, standardize toggle), the display mode, and the appearance bull / bear colors.
Parameters
| Parameter | Default | Description |
|---|---|---|
| Basis Length | 21 | Lookback used to calculate the rolling median basis (HLC3). |
| Smoothing Length | 21 | EMA length applied to the raw oscillator to produce the Smooth MCD line. |
| Signal Length | 14 | EMA length used for the Signal line. |
| Standardize | True | Normalize the oscillator by average candle range so values can use fixed OB/OS zones. |
Display
| Parameter | Default | Description |
|---|---|---|
| Display Mode | All | All = lines + histogram. Fast = histogram only. Slow = lines only. Super Slow = colored line filled to zero with strength shading. |
Appearance
| Parameter | Default | Description |
|---|---|---|
| Bullish Color | #00FFBB | Bullish lines, fills, and positive histogram bars. |
| Bearish Color | #FF1100 | Bearish lines, fills, and negative histogram bars. |
🧠 How It Works
Each bar runs HLC3 binning, the rolling median, the standardization step, and the EMA smoothing chain.
- HLC3 input + rolling median. sHlc3[0] = (high + low + close) / 3. The basis is the median of the last BasisLength HLC3 values. The median is computed by sorting a reusable buffer (size BasisLength) — robust to outliers, well-defined even with single-spike data.
- Raw oscillator. mcd = close − basis. The deviation of close from the median basis. Positive = price above the median; negative = below.
- Standardization (optional). If Standardize is on, divide mcd by EMA(High − Low, BasisLength) and multiply by 100. The output is in ‘percent of average candle range’ units, so OB/OS bands work universally. The fixed reference lines at ±200, ±250, ±300 only make sense when Standardize is on.
- Smooth MCD and Signal. SmoothMcd = EMA(mcd, SmoothLength). Signal = EMA(SmoothMcd, SignalLength). Standard MACD-style chain — the smooth line drives the major signals; the signal line is the slower confirming overlay.
- Histogram. Histogram = SmoothMcd − Signal. Color = bull tone if positive, bear if negative. State-driven shading — bars get darker when the absolute value is increasing (momentum building) and lighter when decreasing (momentum fading).
- Display mode routing. All = SmoothMcd + Signal lines + histogram. Fast = histogram only. Slow = lines only. Super Slow = SuperSlow line in bull/bear color filled to zero with translucent strong / weak shading. The mode setting toggles which Plot.Reset() calls fire each bar.
The indicator is non-repainting — basis median and all EMAs are computed once on closed-bar data.
🛠️ Using It in a Strategy
Dynamic Median Momentum Oscillator works as both an entry generator (cross of SmoothMcd through zero) and a confirmation gate (positive momentum required for longs). The example below uses a histogram-based entry: enter long when the histogram crosses above zero from below; enter short on the symmetric down-cross.
Below is the lifecycle: instantiate in State.DataLoaded, then in OnBarUpdate watch for histogram zero-crosses.
private DynamicMedianMomentumOscillator dmmo;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "DmmoStrategyExample";
}
else if (State == State.DataLoaded)
{
dmmo = DynamicMedianMomentumOscillator(
21, // Basis Length
21, // Smoothing Length
14, // Signal Length
true, // Standardize
DynamicMedianMomentumOscillator_Mode.All // Display Mode
);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 80) return;
double h0 = dmmo.Histogram[0];
double h1 = dmmo.Histogram[1];
bool crossUpZero = h0 > 0 && h1 <= 0;
bool crossDownZero = h0 < 0 && h1 >= 0;
if (crossUpZero && Position.MarketPosition != MarketPosition.Long) EnterLong();
if (crossDownZero && Position.MarketPosition != MarketPosition.Short) EnterShort();
}
Histogram + zero-cross is one strategy use; another option is to read dmmo.SmoothMcd[0] > 200 as a saturated-bull filter in standardize mode, or pair the SmoothMcd with the Signal line for a classic MACD crossover.
Public Outputs
| Output | Type | Description |
|---|---|---|
| SmoothMcd[0] |
Series | EMA-smoothed (close − median basis), optionally standardized. The primary momentum line. |
| Signal[0] |
Series | EMA of Smooth MCD. The signal line. |
| Histogram[0] |
Series | Smooth MCD − Signal. Standard MACD-style histogram. |
| SuperSlow[0] |
Series | Same as Smooth MCD; populated only when Mode = SuperSlow for the colored-line + zero-fill render. |
🔄 Conversion Notes
A few things changed in the translation from Pine Script to NinjaScript:
Rolling median via reusable sort buffer. Pine’s ta.median primitive translates to a per-bar copy of the last BasisLength HLC3 values into a reusable double[], sorted, midpoint pulled. The buffer is allocated once in DataLoaded so the per-bar cost is the sort itself, not the allocation.
Standardization via EMA(High − Low). Pine’s ta.ema(high - low, basisLength) becomes a wrapper EMA over a derived Series<double>. The standardize branch divides mcd by that EMA and multiplies by 100 so the OB/OS bands at ±200 / ±250 / ±300 hold across assets.
SharpDX OB/OS rectangle bands. Pine’s fill() between OB hlines becomes per-render SharpDX rectangles in the bull / bear tone with quantized alpha — translucent gray fades for the standard OB/OS, more saturated for the extreme bands.
State-driven histogram coloring. A second PlotBrushes branch tracks |hist| versus |hist[1]|. Lighter brush when extending toward zero (fading), darker when extending away from zero (building). One plot, one PlotBrushes per bar.
Super Slow zero-fill via SharpDX. Pine’s fill(plot, hline(0)) for the super-slow render becomes a SharpDX trapezoid between the SuperSlow line and the y=0 anchor in OnRender. Bull-side fills above zero in bull color; bear-side below in bear color.
Display mode routing via Plot.Reset. Pine’s per-mode color.new(c, 100) hide-trick becomes per-bar Values[i].Reset() calls so plots that aren’t part of the active mode genuinely don’t render rather than being plotted with full transparency.
📦 Download
The full source is available as a free NinjaScript Archive. To install:
- Download the
.zipfile below. - In NinjaTrader 8, go to Tools → Import → NinjaScript Add-On.
- Select the downloaded
.zipfile. - The indicator will appear under Indicators → indTradingView → Dynamic Median Momentum Oscillator [AlgoAlpha] on your chart.
📊 Chart Example

Dynamic Median Momentum Oscillator on a 1-minute chart with default settings (Basis=21, Smooth=21, Signal=14, Standardize=on, Mode=All). The Smooth MCD line in white tracks momentum; the orange Signal line confirms; the histogram colors fill / fade by extending vs decaying. Reference lines at ±200 / ±250 / ±300 mark the standardized OB/OS / extreme bands.
The original Pine Script™ code is by AlgoAlpha and is licensed under the Mozilla Public License 2.0 (MPL 2.0). This NinjaTrader 8 adaptation is by MyDailyTake.com. The use of AlgoAlpha’s name or adapted code does not imply endorsement by the original author.








