Gamestudio Links
Zorro Links
Newest Posts
Zorro 3.01 recoded MMI function issue
by TipmyPip. 06/04/26 05:44
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
XTB
by pr0logic. 05/18/26 12:27
Purchase A8 full licence version
by NeoDumont. 05/13/26 20:17
Black Book, 4th edition
by TipmyPip. 05/11/26 08:40
AUM Magazine
Latest Screens
Dorifto samurai
Shadow 2
Rocker`s Revenge
Stug 3 Stormartillery
Who's Online Now
0 registered members (), 6,352 guests, and 4 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Seraphinang, Koti, curry, DeepxKalsi, Samed
19219 Registered Users
Active Threads | Active Posts | Unanswered Today | Since Yesterday | This Week
Zorro Scripts
06/04/26 05:44
It can affect backtesting when MMI is used in a trade condition, filter, optimizer, or ML feature, because the changed MMI value can change whether a signal is true or false.

The original MMI code calculates a median over TimePeriod and then counts rising/falling behavior around that median. Zorro’s indicator source shows the old version using TimePeriod = Min(TimePeriod,g->nBar-1); and Median(Data,TimePeriod). The Median function sorts the data and returns the middle value within the given period.

When the backtest can change
1. When TimePeriod is even

Old:

var m = Median(Data,TimePeriod);

New:

var m = Median(Data,TimePeriod|1);

If TimePeriod = 100, then:

TimePeriod|1 = 101

So the median is calculated from 101 values instead of 100.

That can shift the median slightly. Since MMI compares every value against the median:

if(Data[i] > m && Data[i] > Data[i-1])
nl++;
else if(Data[i] < m && Data[i] < Data[i-1])
nh++;

a small median shift can change nl or nh, which changes the returned MMI value.

This matters if your strategy does something like:

if(MMI(Price,100) > 75)
enterLong();

A value changing from 74.9 to 75.2 can create a trade in one version but not the other.

2. Near the beginning of the backtest or WFO cycle

Old:

TimePeriod = Min(TimePeriod,g->nBar-1);

New:

TimePeriod = Min(TimePeriod,g->nBar-2);

The new version uses one less available bar when history is short.

This can affect the first valid bars after LookBack, or the beginning of a walk-forward cycle, especially if TimePeriod is close to the available history length.

Zorro uses LookBack to execute bars before trading begins so indicators have enough history. The manual says the first bar where trades can be entered is greater than or equal to LookBack, and LookBack should cover the longest period of all used indicators, assets, and time frames.

So this change can affect backtesting mostly when:

LookBack ? MMI period

or when TimePeriod is optimized and sometimes becomes large.

3. When MMI is used as a filter

Example:

vars Price = series(priceClose());
var MeanState = MMI(Price,100);

if(MeanState > 75)
enterLong();

If the old version gives:

MMI_old = 74.8

and the new version gives:

MMI_new = 75.3

then the trade only happens with the new version.

That can change:

entry timing, number of trades, profit factor, drawdown, optimized parameters, WFO results

The Zorro manual notes that indicators often become buy/sell signals when they reach thresholds, cross each other, or cross the price curve.

4. When MMI period is optimized

This is a big one.

Example:

int MMIPeriod = optimize(100,50,300,10);
var M = MMI(Price,MMIPeriod);

If some optimized values are even, the new version internally turns the median length odd:

100 -> 101
120 -> 121
200 -> 201

So the optimizer may find a different best parameter than before.

Zorro’s documentation specifically warns that when optimizing an indicator time period, LookBack should be set to at least the maximum period, otherwise the backtest period can change with the optimized value and affect results unexpectedly.
5 155 Read More
Zorro Scripts
06/04/26 05:38
How to test whether your backtest is affected

You can copy both versions into your script and compare them bar by bar.

Code
// Old MMI version
var MMI_old(vars Data,int TimePeriod)
{
    TimePeriod = Min(TimePeriod,1000);
    checkLookBack(TimePeriod);
    TimePeriod = Min(TimePeriod,g->nBar-1);

    if(TimePeriod < 2)
        return 75;

    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);
}


// New MMI version
var MMI_new(vars Data,int TimePeriod)
{
    TimePeriod = Min(TimePeriod,1000);
    checkLookBack(TimePeriod);
    TimePeriod = Min(TimePeriod,g->nBar-2);

    if(TimePeriod < 2)
        return 75;

    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);
}


function run()
{
    BarPeriod = 60;
    LookBack = 300;

    asset("EUR/USD");

    vars Price = series(priceClose());

    int Period = 100;

    var OldMMI = MMI_old(Price,Period);
    var NewMMI = MMI_new(Price,Period);

    plot("Old MMI",OldMMI,NEW,BLUE);
    plot("New MMI",NewMMI,0,RED);
    plot("Difference",NewMMI-OldMMI,NEW,GREEN);

    static int ValueDiffs = 0;
    static int SignalDiffs = 0;

    if(!is(LOOKBACK))
    {
        if(abs(NewMMI-OldMMI) > 0.0001)
            ValueDiffs++;

        int OldSignal = OldMMI > 75;
        int NewSignal = NewMMI > 75;

        if(OldSignal != NewSignal)
        {
            SignalDiffs++;
            printf("\nBar %i: Old MMI %.2f, New MMI %.2f",Bar,OldMMI,NewMMI);
        }
    }

    if(is(EXITRUN))
    {
        printf("\nMMI value differences: %i",ValueDiffs);
        printf("\nMMI signal differences: %i",SignalDiffs);
    }
}



What to look for

If the green Difference plot is often zero, your backtest is probably not affected.

If you see many lines like:

Old MMI 74.95, New MMI 75.12

and your system uses a threshold near 75, then your backtest can change.

The highest-risk cases are:

Code
if(MMI(Price,Period) > 75)
if(MMI(Price,Period) < 50)
if(crossOver(MMI_Series,Threshold))


The lowest-risk case is when MMI is only plotted and not used for trading decisions.
5 155 Read More

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