Gamestudio Links
Zorro Links
Newest Posts
Zorro 3.01 recoded MMI function issue
by 11honza11. 06/02/26 11:39
SGT_FW
by Aku_Aku. 05/31/26 11:05
ZorroGPT
by TipmyPip. 05/28/26 01:43
Issues resuming trades on Demo account
by Martin_HH. 05/22/26 13:31
AUM Magazine
Latest Screens
Dorifto samurai
Shadow 2
Rocker`s Revenge
Stug 3 Stormartillery
Who's Online Now
1 registered members (Quad), 4,964 guests, and 1 spider.
Key: Admin, Global Mod, Mod
Newest Members
Seraphinang, Koti, curry, DeepxKalsi, Samed
19219 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Zorro 3.01 recoded MMI function issue #489443
Yesterday at 16:02
Yesterday at 16:02
Joined: Apr 2024
Posts: 9
11honza11 Offline OP
Newbie
11honza11  Offline OP
Newbie

Joined: Apr 2024
Posts: 9
Hi, after upgrading to 3.01 one of my strategy using MMI got clearly different performance metrics in a backtest. I found that recoded MMI is the culprit. It returns different data than the previous one. So I am wondering which version is "flawed" and which one is "correct".

Re: Zorro 3.01 recoded MMI function issue [Re: 11honza11] #489444
21 hours ago
21 hours ago
Joined: Sep 2017
Posts: 302
TipmyPip Offline
Senior Member
TipmyPip  Offline
Senior Member

Joined: Sep 2017
Posts: 302
I would not judge this only by the changed performance metrics. I would first compare both MMI implementations against the published/reference formula. If the new 3.01 MMI differs from that formula, then the recoded version is likely wrong. If the old version differed, then the old backtest results were based on a flawed indicator. Since MMI is often used as a trend filter, even small output differences can strongly affect entries/exits and performance.

The correct MMI should follow the reference definition: calculate the median of the data window, then count cases where price is above median and continues upward, or below median and continues downward. The classic Zorro/Financial Hacker version is:

Code
var MMI(var *Data,int Length)  
{  
  var m = Median(Data,Length);  
  int i, nh=0, nl=0;
  for(i=1; i<Length; i++) {
    if(Data[i] > m && Data[i] > Data[i-1])
      nl++;
    else if(Data[i] < m && Data[i] < Data[i-1])
      nh++;
  }
  return 100.*(nl+nh)/(Length-1);
}


Zorro’s manual says MMI measures mean-reversal tendency in a 0–100% range, with random numbers around 75%, and that source code is in indicators.c.

So the practical answer is: compare both versions against this reference formula. The version matching this formula is the correct one. If 3.01 changed the median handling, indexing direction, equal-value handling, or the denominator, it can absolutely produce different backtests.

Re: Zorro 3.01 recoded MMI function issue [Re: 11honza11] #489448
9 hours ago
9 hours ago
Joined: Apr 2024
Posts: 9
11honza11 Offline OP
Newbie
11honza11  Offline OP
Newbie

Joined: Apr 2024
Posts: 9
Thank you for a reply! That was the first thing I did - compared both versions and I can confirm the source code is different, and when I copy pasted the previous implementation to my custom indicators script and use it, the backtest showed the original performance metrics - confirming the recoded version indeed changed the strategy.

Original code (indicators.c):
Code
// Zorro's Market Meanness Index
var MMI(var* Data,int TimePeriod)
{
// clip time period to history length
	TimePeriod = Min(TimePeriod,1000);
	checkLookBack(TimePeriod);
	TimePeriod = Min((uint)TimePeriod,g->nBar-1);
	if(TimePeriod < 2) return 75;
// calculate MMI statistics
	var m = Median(Data,TimePeriod); 
	int i, nh=0, nl=0;
	for(i=1; i<TimePeriod; i++) {
		if(Data[i] > m && Data[i] > Data[i-1])
			nl++;
		else if(Data[i] < m && Data[i] < Data[i-1])
			nh++;
	}
	return 100.*(nl+nh)/(TimePeriod-1);
}



Recoded version (indicators.c):
Code
// Zorro's Market Meanness Index
var MMI(var* Data,int TimePeriod)
{
	checkLookBack(TimePeriod);
// clip time period to history length
	TimePeriod = Min((uint)TimePeriod,g->nBar-2);
	if(TimePeriod < 2) return 75;
// calculate MMI statistics
	var m = Median(Data,TimePeriod|1); 
	int i, nh=0, nl=0;
	for(i=1; i<TimePeriod; i++) {
		if(Data[i] > m && Data[i] > Data[i-1])
			nl++;
		else if(Data[i] < m && Data[i] < Data[i-1])
			nh++;
	}
	return 100.*(nl+nh)/(TimePeriod-1);
}


Here are the changes
[Linked Image]

It seems like the previous version is matching the "classic" version you mentioned slightly more, probably indicating the recoded version is somehow flawed.

Attached Files
mmi.png (14 downloads)
Last edited by 11honza11; 9 hours ago.

Moderated by  Petra 

Gamestudio download | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1