Visual KF-MRO (Kalman-Filter Mean-Reversion Oscillator) – quick overview

Visual KF-MRO (Kalman-Filter Mean-Reversion Oscillator) – quick overview

  • Core logic
    1. Runs a 1-D Kalman filter on the price to extract the “fair value” (kalman_estimate).
    2. Plots the real-time Z-score of the Kalman error (price – estimate).
    3. Fixed or dynamic thresholds
    • Static: user-set UpperThreshold / LowerThreshold.
    • Dynamic: Bollinger Bands of the Z-score.
  • Signal engine
    Bull = Z-score ≤ lower band and (optional) cross above its EMA.
    Bear = Z-score ≥ upper band and cross below its EMA.
  • Visual package
    • Histogram bar (Z-score) + EMA line.
    • Colored overbought / oversold zones.
    • Up / down arrows on the price panel with tick offset.
    • Optional price-bar repaint (blue = bull, fuchsia = bear).
    • Audio alert once per bar (Alert1.wav by default).
  • Safety & robustness
    • Early-bar guard (CurrentBar < Z_Period).
    • Anti-NaN: any invalid math is forced to zero.
    • All parameters exposed via [NinjaScriptProperty] for easy optimisation.
  • Customization highlights
    • Q / R noise, Z-score period, EMA length.
    • Toggle dynamic bands, EMA filter, price-bar painting.
    • Independent color/opacity settings for every element.

Drop the file into NinjaTrader 8 → Indicators, compile, and add it to a chart in its own panel. Adjust the thresholds to suit your market / timeframe and let the arrows guide your entries. Happy trading!

2 Likes

I wouldn’t mind putting this together. Instead of triggering an alert on every signal bar, consider integrating a volume-awareness filter:

Identify the highest volume bar in a recent lookback window.

Trigger the alert only when price returns to the price level (or zone) of that high-volume bar, signaling interaction with significant liquidity.
This could reduce noise and align alerts with meaningful participation zones.

(Pseudo-Code )
// Define lookback period for volume analysis
int volumeLookback = 20;
double highVolume = 0;
double highVolumePrice = 0;

// OnBarUpdate logic
if (CurrentBar < volumeLookback)
return;

// Step 1: Scan past N bars for highest volume
for (int i = 1; i <= volumeLookback; i++)
{
if (Volume[i] > highVolume)
{
highVolume = Volume[i];
highVolumePrice = (High[i] + Low[i]) / 2; // Mid-price of the high-volume bar
}
}

// Step 2: Check if current price is within tolerance of that price zone
double toleranceTicks = 2; // adjustable — defines the zone width
double tickSize = TickSize;
double lowerBound = highVolumePrice - (toleranceTicks * tickSize);
double upperBound = highVolumePrice + (toleranceTicks * tickSize);

bool priceInVolumeZone = Close[0] >= lowerBound && Close[0] <= upperBound;

// Step 3: Combine with Z-score signal condition
if (BullSignalCondition && priceInVolumeZone)
{
Draw.ArrowUp(…);
Alert(“BullVolumeAlert”, Priority.High, “Bullish Z-score signal at volume zone”, “Alert1.wav”, 0, Brushes.Blue, Brushes.Transparent);
}
else if (BearSignalCondition && priceInVolumeZone)
{
Draw.ArrowDown(…);
Alert(“BearVolumeAlert”, Priority.High, “Bearish Z-score signal at volume zone”, “Alert1.wav”, 0, Brushes.Fuchsia, Brushes.Transparent);
}

Discuss this with ChatGPT 3o Pro and you’ll be surprised at what you build!

1 Like

Please - is there a working code? thank u