Different results of function in chart and exploration

Hi All.

Please help me to understand following situation. I have code:

SetBarsRequired(sbrAll, sbrAll);
function B(array, period)
{
	average = Cum(array)/period; 
	last_known_average_as_num = StrToNum( NumToStr(average, format = 10.10));
        // Applying here numeric value of cumulative average to array. 
	return  Cum( ( array - last_known_average_as_num ) ^ 2 );
}

inc_a = cum(1);
result = B(inc_a, inc_a);
Plot( result, "result", colorYellow ); 
if (Status("action") == actionExplore)        
{     Filter = 1; AddColumn(result, "result", 1.8);AddColumn(inc_a, "inc_a", 1.8);	     }    

When to run this code in Chart all is great and result is exactly what i need. See screenshot below.
result1
When to run same code in exploration result is very different.
result2
Notice please that on same date values are different.
I found that in exploration mode function

 NumToStr(average, format = 10.10)

works differently than in chart. So please, can anyone suggest, which is best way to lock value from one array, and apply this value to range of another array. I need that working in both chart and exploration mode, tried different ways but always having issues with exploration.

@alexz why are you using that string conversion/back to a number?
Passing an array to NumToStr() in a chart return a different value for each bar (like SelectedValue()).

From the variable name (last_known_average_as_num) I suppose you want to use the LastValue() of the average.

I tried, this not helps, LastValue() returns last available value which is located in future, at last available bar. But I need numeric value for average calculated under current bar, every next bar I need a numeric (not array) cumulative value of average on date of current bar.

You seriously need to read How AFL works

All you need is this

function B(array, period)
{
	average = Cum(array)/period; 
	return Cum( ( array - average ) ^ 2 );
}
1 Like
function B(array, period)
{
	average = Cum(array)/period; 
	return Cum( ( array - average ) ^ 2 );
}

I know how AFL works ) but some tiny details make me crazy. So this code you suggesting works not like i need. this is classic array function, where if to tell other words result will be Cumulative of ( (array[1] - average[1])^2, (array[2] - average[2])^2, ... (array[N] - average[N])^2 ). But need a way to calculate on following manner:

Say for 3rd bar i need:
Cumulative of ( (array[1] - average[3])^2, (array[2] - average[3])^2, array[3] - average[3])^2 ).
for Bar N:
Cumulative of ( (array[1] - average[N])^2, (array[2] - average[N])^2, ... (array[N] - average[N])^2 ).

The code i posted in first post works good for my needs but only in chart. Same code if to run in exploration gives very different results. So that was my quation how to adopt this code for exploration to have exactly same results.

One possibility is using AFL loop (keep in mind: in general AFL looping is slower than inbuilt array solutions).
(Have not come up with non-AFL loop version yet. Maybe Tomasz...).

But below one works (see pic).

function B(array, period) {
	/// @link https://forum.amibroker.com/t/different-results-of-function-in-chart-and-exploration/7180/6
	global average;
	
	average = cum(array) / period;
	
	for ( i = 0; i < BarCount; i++ ) {
		x = average[i];	
		
		csum = 0;
		for ( j = 0; j <= i; j++ ) {	
		//for ( j = i; j >= 0; j-- ) {				
			y = (array[j] - x);							
			csum += y^2;	

			if( i < 6 )
				printf( "\ni:%g\tj:%g\tarray:%g\tavg:%g\t(arr-avg): %g\t(csum^2): %g", i, j, array[j], x, y, csum );
		}	
		
		result[i] = csum;	
	}

	return result;
}

inc_a = cum(1);
x = B(C, inc_a);

Plot( average, "Avg", colorDefault );
Plot( x, "B", colorDefault );
Plot( C, "Price", colorDefault, styleCandle );

451

thanks fxshrat, similar idea to use nested loops i got while typed explanation to your first reply. that really works like i need! so current question is solved about way how to calculate.

Onre more really remains - is performance really much slower when function used in backtesting,. Wondering if there is array style method to do same calculations. )

Then why do you make me wasting time preparing post? I don't get it.

Yes (as for upper function).

One possibility for much faster execution: converting AFL loop to DLL function using ADK of https://www.amibroker.com/download.html. If you can't convert yourself then you may send PM.

Thank you very much! without talk with you my solution will be not possible. You helped a lot!

Indeed, this seemed a good example to measure the compiled code performance vs. the AFL version: on average it runs over 300 times faster! :rocket:

(My test was done using C++ code, built with Microsoft VS 2015 to a 32-bit DLL using the AmiBroker ADK).

2 Likes