Optimize period slope with Price and MFI

Hi, I am back to amibroker, (french user since 2000)
I want to know if someone know a « tips » to improve this working code
It returns the best correlation period between slope price and slope MFI

_SECTION_BEGIN("Correlation Variable");

periods = Param( "periodsIndicator", 14, 3, 28, 1 );
myArray = MFI(periods);
periodslope = Param( "periodSlope", 9, 3, 28, 1 );
k[0] = 0;

function varPeriod (periodslope)
{
return Correlation(LinRegslope(myArray,periodslope),LinRegslope(Close,periodslope),periodslope);
}

for (i = periodslope ; i < BarCount; i++)
{
for  (n = 9 ; n < 29; n++)
{
varArray = varPeriod(n);
if (varArray[i] > 0.5)
break;
}
k[i] =  n;
}

Plot( k , "Test", colorwhite );
//Plot( LinRegslope(myArray,periodslope) , "Test", colorGreen );
//Plot( LinRegslope(myArray,k) , "Test", colorwhite );

_SECTION_END();
_SECTION_BEGIN("Correlation Variable");
periods = Param( "periodsIndicator", 14, 3, 28, 1 );
myArray = MFI(periods);
periodslope = Param( "periodSlope", 9, 3, 28, 1 );

function varPeriod( periodslope )
{
    arr1 = LinRegslope( myArray, periodslope );
    arr2 = LinRegslope( C, periodslope );
    return Correlation(arr1, arr2, periodslope);
}

/// @link https://forum.amibroker.com/t/optimize-period-slope-with-price-and-mfi/19740/1
/// Removed (nested) BarCount loop
k = 0;
cum_cond = 0;
for ( n = 9; n < 29; n++ ) {   
   cond = varPeriod( n ) > 0.5;
   cum_cond += cond;
   k += IIf(cond AND cum_cond == 1, n, 0);      
}
k = IIf(k == 0, Null, k);
// Or
//k = IIf(k == 0, 9, k);
// ...

Plot(k, "k", colorWhite, styleStaircase );
//Plot( varPeriod( SelectedValue(k) ), "Test", colorRed, styleOwnScale );

//Plot( LinRegslope(myArray,periodslope) , "Test", colorGreen );
//Plot( LinRegslope(myArray,k) , "Test", colorwhite );
_SECTION_END();
6 Likes

fxshrat
Thanks for your reply, +++
Interesting afl code. Let me digest it. And compare results

fxshrat
your light code matches perfectly
Bravo !!!

Can you explain me for what use the code?
regards

change and uncheck arr_period = IIf(k == 0, min_rng, k);
or you'll get an error

the system is simple:
high correlation trade the slope
low correlation trade divergence
between play worldofwarcraft :wink:

@htordeux,

There is no error in my code added to your one.

The error comes from your original function varPeriod where you did not ensure error free run when period becomes NULL or returns values below 1.

So you can prevent Error 52 by e.g. doing this

function varPeriod( periodslope )
{
	if ( Nz(periodslope) > 0 ) {
		arr1 = LinRegslope( myArray, periodslope );
		arr2 = LinRegslope( C, periodslope );
		result = Correlation(arr1, arr2, periodslope);
	} else 
		result = Null;
    return result;
}

As for arr_period...
The purpose of setting to NULL is to ignore cases where there is not any period of range of periods found returning TRUE for cond = varArray > 0.5;

So by using line arr_period = IIf(k == 0, Null, k); we assign NULL to FALSE results of period.

13

Here is modification so now there isn't Error 52 anymore if using your function (I tested with other one before without re-checking yours before posting)

_SECTION_BEGIN("Correlation Variable");
periods = Param( "periodsIndicator", 14, 3, 28, 1 );
myArray = MFI(periods);
periodslope = Param( "periodSlope", 9, 3, 28, 1 );

function varPeriod( periodslope )
{
	if ( Nz(periodslope) > 0 ) {
		arr1 = LinRegslope( myArray, periodslope );
		arr2 = LinRegslope( C, periodslope );
		result = Correlation(arr1, arr2, periodslope);
	} else 
		result = Null;
    return result;
}

function VariablePeriodCorrelation( period )
{
	/// code source
	/// @link https://forum.amibroker.com/t/how-to-make-any-function-accepting-variable-period/708
	minperiod = LastValue(Lowest(period));
	maxperiod = LastValue(Highest(period));
	
	result = Null;	
	for( p = minperiod; p <= maxperiod; p++ )
	{	
		ind = varPeriod( p );		
		result = IIf( period == p, ind, result );
	}	
	return result;
}

/// Code source 
/// @link https://forum.amibroker.com/t/optimize-period-slope-with-price-and-mfi/19740/7
/// Removed (nested) BarCount loop
k = 0;
min_rng= 9;// min period 
max_rng = 29;// max period
cum_cond = 0;
for ( n = min_rng; n < max_rng; n++ ) {	
	varArray = varPeriod( n );
	cond = varArray > 0.5;
	cum_cond += cond;
	k += IIf(cond AND cum_cond == 1, n, 0);		
}
// period array
arr_period = IIf(k == 0, Null, k);
// Or
//arr_period = IIf(k == 0, min_rng, k);
// ...

Plot(arr_period, "arr_period", colorWhite, styleStaircase );
indicator = VariablePeriodCorrelation(arr_period);
//indicator = LinRegslope(myArray,arr_period);
Plot(indicator, "VariablePeriodIndicator", colorRed, styleOwnScale);
_SECTION_END();

The code takes a range of periods (type number) and iterates that range and stores the first period per element in array where cond = varArray > 0.5; returns TRUE . So he only wants to take periods into account (of chosen range) where correlation is greater 0.5 at each point in the array. The result is an array of variable periods that you can insert into (variable period) functions (in case of this thread e.g. Correlation ). Native Correlation function of AmiBroker itself allows constant period only but via coding technique as shown by Tomasz's variable period function one can use array period for such functions also.

Thanks for you explanation.
Regards

Right, this was a good learning post for variable period , showing afl possibility instead working with barcount loop.