Market Manipulation Index (MMI): A Powerful Tool to Detect Market Irregularities
In today's highly automated markets, price movements often don't reflect pure supply and demand. Instead, they can be influenced by large players and algorithmic manipulation. The Market Manipulation Index (MMI) is a technical indicator designed to expose such behavior by quantifying market irregularity.

What Is MMI?

The MMI measures how predictable or structured a market’s behavior is, based on:

Sine wave deviation: Measures how well price movements align with cyclical patterns.

Predictability analysis: Uses linear regression to see how predictable prices are based on past data.

Spectral energy analysis (optional): Assesses noise vs. structure via smoothed price bands.

What Does MMI Tell You?

Low MMI (< 0.3): A clean, trending, or mean-reverting market — easier to trade.

High MMI (> 0.7): A noisy or manipulated market — harder to predict and trade reliably.

How Is MMI Calculated?

At its core, MMI uses:

Rolling volatility (variance)

EMA-smoothened error estimates

Deviation from sine waves and linear predictions

It normalizes results to a 0–1 scale, highlighting when the market departs from natural structures.

How To Use MMI

As a filter: Only take trades when MMI is low (e.g., < 0.3).

As a warning: Avoid entering trades during high MMI spikes.

Combined with VWAP: Use VWAP-based MMI to detect price distortions around fair value.

With other signals: Use MMI to confirm or reject breakout or reversal signals.

Practical Trading Tip

Pair MMI with volume or VWAP:

If price deviates strongly from VWAP and MMI is high, manipulation may be in play.

If price returns to VWAP and MMI drops, the market may stabilize — a good entry zone.

Available in Zorro Trader

This indicator can be implemented in lite-C for Zorro, fully compatible with live and backtesting. You can:

Visualize MMI over time

Trigger signals from MMI zones

Customize sensitivity via adaptive smoothing and windows

Conclusion

MMI is not just an indicator — it’s a market integrity scanner. When combined with volume, VWAP, and structure-aware strategies, it becomes a powerful filter to protect traders from erratic or manipulated conditions.

Use MMI to step away from noise — and trade only the moments that matter.

Code
var clamp(var value, var min, var max)
{
	if (value < min) return min;
	if (value > max) return max;
	return value;
}

var adaptiveWinLength()
{
	var atr_val = ATR(14);
	return max(10, round(50 * (atr_val / priceClose()) * 1.0));
}

var sineWave()
{
	return sin(2 * PI * Bar / 20); // SINE_LEN = 20
}

var spectralEnergy(int baseWin)
{
	static var* lowSeries;
	static var* highSeries;

	var lowBand = EMA(priceClose(), 34) - EMA(priceClose(), 89);
	var highBand = priceClose() - EMA(priceClose(), 8);

	lowSeries = series(lowBand);
	highSeries = series(highBand);

	var energyLow = Variance(lowSeries, baseWin);
	var energyHigh = Variance(highSeries, baseWin);

	var spectralRatio = energyHigh / (energyHigh + energyLow + 0.000001);
	return clamp(spectralRatio, 0, 1);
}

var predictabilityMI(int window)
{
	static var* priceSeries;
	priceSeries = series(priceClose());

	var x1 = priceClose(1);
	var x2 = priceClose(2);
	var y = priceClose();

	var sum_x1 = EMA(x1, window);
	var sum_x2 = EMA(x2, window);
	var sum_y = EMA(y, window);

	var sum_x1x1 = EMA(x1 * x1, window);
	var sum_x2x2 = EMA(x2 * x2, window);
	var sum_x1x2 = EMA(x1 * x2, window);
	var sum_x1y = EMA(x1 * y, window);
	var sum_x2y = EMA(x2 * y, window);

	var denom = sum_x1x1 * sum_x2x2 - sum_x1x2 * sum_x1x2;
	var a = ifelse(denom != 0, (sum_x2x2 * sum_x1y - sum_x1x2 * sum_x2y) / denom, 0);
	var b = ifelse(denom != 0, (sum_x1x1 * sum_x2y - sum_x1x2 * sum_x1y) / denom, 0);

	var y_hat = a * x1 + b * x2;
	var residual = y - y_hat;
	var mse_pred = EMA(pow(residual, 2), window);
	var var_price = Variance(priceSeries, 50);

	return clamp(mse_pred / var_price, 0, 1);
}

var sineMI(int window)
{
	static var* priceSeries;
	priceSeries = series(priceClose());

	var sine = sineWave();
	var price = priceClose();
	var sine_dev = sine - EMA(sine, window);
	var price_dev = price - EMA(price, window);
	var mse_sine = EMA(pow(price_dev - sine_dev, 2), window);
	var var_price = Variance(priceSeries, 50);

	return clamp(mse_sine / var_price, 0, 1);
}

// === Main Indicator Function ===

function run()
{
	set(PLOTNOW);

	if (Bar < 60) return;

	int win = adaptiveWinLength();

	var mi_sine = sineMI(win);
	var mi_pred = predictabilityMI(win);
	var mi_spec = spectralEnergy(50);

	var cmi_raw = (mi_sine + mi_pred + mi_spec) / 3;
	var cmi = EMA(cmi_raw, 5); // SMOOTH = 5

	plot("MMI", cmi, LINE, RED);
	plot("Low", 0.3, LINE, GREEN);
	plot("High", 0.7, LINE, ORANGE);
}