Code efficiency HELP

 

I am using the following to track the last 100 ticks in an internal buffer of the EA and calculate the averages:

if( Ask != TickAsk[0] || Bid != TickBid[0] )

{

for(int f=100-1;f>0;f--)

{

TickAsk[f] = TickAsk[f-1];

TickBid[f] = TickBid[f-1];

}

TickAsk[0]=Ask;

TickBid[0]=Bid;

}

int b=0;

while( TickAsk != 0 && b < 100 )

{

btotal+=BSSfpi;

atotal+=SBBfpi;

b++;

}

if(b!=0)

{

b_avg = btotal / (b);

a_avg = atotal / (b);

}

The problem I am having is that once the buffers fill up, this routine taxes the cpu and extends the EA iteration time from about 2ms to around 7ms.

Is there a more effective way to accomplish this task?

 

cyclic buffer

Maybe use cyclic buffer; something like the following?

#define SIZE 100

double buffer[ SIZE ];

int start_index = 0;

void push(double data) {

start_index -= 1;

if ( start_index < 0 )

start_index = SIZE - 1;

buffer[ start_index ] = data;

}

double get(int index) {

index += start_index;

while ( index >= SIZE )

index -= SIZE;

return( buffer[ index ] );

}

That would avoid moving data. Then, if you only use it in the way of your code, then you could drop the buffers completely, and instead keep the rolling

average. But I suppose there's some other use of them.

Even so, if the accumulated values are constant (i.e. "BSSfpi" at this tick equals "BSSfgi" at the next tick), then a rolling calculation would be faster. I.e., keep "btotal" and "atotal" as static so you can refer to their values of the prior tick, and keep static "b100 = BSSfpi[100]" and "a100", so you can reduce "btotal" and "atotal" by prior "b100" and "a100" before adding only the most recent "BSSfpi[0]" and "SBBfpi[0]".

not sure if that was confusing enough :-)

 

If you want only average do you really need a buffer?

Please note i didnt test it, but if doesnt work i think it is still possible to get away without buffers.

int start(){

static int cnt = 0;

static double prevAsk = 0, totalAsk = 0

if(cnt >= 100){

cnt--;

totalAsk -= prevAsk;

}

totalAsk += Ask;

prevAsk = Ask;

cnt++;

double avgAsk = totalAsk / cnt;

}

 

If you only want average do you really need a buffer.

Please note I didnt test this but if it doesnt work I think it is still possible to get away without buffers.

int start(){

static int cnt = 0;

static double prevAsk = 0, totalAsk = 0

if(cnt >= 100){

cnt--;

totalAsk -= prevAsk;

}

totalAsk += Ask;

prevAsk = Ask;

cnt++;

double avgAsk = totalAsk / cnt;

}

 
ralph.ronnquist:
Maybe use cyclic buffer; something like the following?
#define SIZE 100

double buffer[ SIZE ];

int start_index = 0;

void push(double data) {

start_index -= 1;

if ( start_index < 0 )

start_index = SIZE - 1;

buffer[ start_index ] = data;

}

double get(int index) {

index += start_index;

while ( index >= SIZE )

index -= SIZE;

return( buffer[ index ] );

}

That would avoid moving data. Then, if you only use it in the way of your code, then you could drop the buffers completely, and instead keep the rolling

average. But I suppose there's some other use of them.

Even so, if the accumulated values are constant (i.e. "BSSfpi" at this tick equals "BSSfgi" at the next tick), then a rolling calculation would be faster. I.e., keep "btotal" and "atotal" as static so you can refer to their values of the prior tick, and keep static "b100 = BSSfpi[100]" and "a100", so you can reduce "btotal" and "atotal" by prior "b100" and "a100" before adding only the most recent "BSSfpi[0]" and "SBBfpi[0]".

not sure if that was confusing enough :-)

confused* When and where do you call the get() and what value do you pass in "index"?

 

sorry for 2nd pos. something wrong was with this forum.

 

ralph.ronnquist, asmdev,

...both very good ideas. Here is a hybrid that should accomplish what is needed.

Thanks for the replies!!!

void function()

{

static double tickbuffer[100];

static int counter;static bool hit;

if( !hit && counter >= 100 - 1 )

{

hit=true;

}

if( !hit )

{

total+=Ask;

tickbuffer[counter]=Ask;

counter++;

avg=total/counter;

}

else if( hit )

{

if(counter>=100) counter = 0;

total+=Ask;

total-=tickbuffer[counter];

tickbuffer[counter]=Ask;

counter++;

avg=total/100;

}

return;

}
Reason: