Creating a TickCounter using MqlTick and CopyTicks [suggestions plz]

 

Hi there,

I'm still new to OOP and MQL5 in general, and I'm trying to find out a way to use arrays and comparing their different "i" values .

The idea is to create a "tickcounter", and for every "last tick" compare it to the "previous tick" and see if they were different (bigger, smaller) and then to ++ or -- it in the "tickcounter", but, only for the last 1000 ticks received, so, when the "for counter" (i) reaches the end of the array (in size, 1000 as in the code below) it would reset the "tickcounter" back to 0, starting it over again.

I used the "CopyTicks" link from MQL as a base and went from there to this here below:

   MqlTick tick_array[]; //defining array to copy ticks to
   
   // copyticks will return an index referring to tick_array array
   int copied_ticks=CopyTicks(_Symbol,tick_array,COPY_TICKS_TRADE,0,1000);
   int tickcounter; // defining tickcounter as integer
   
   if(copied_ticks>0) // if array is not empty 
     {
      for(int i=0;i<copied_ticks;i++) // for counter ~> 1 to arraysize(1000?)
        {
         MqlTick tick=tick_array[i]; //  assigning current "i" to "tick"
         MqlTick tickPrev=tick_array[i-1]; // assigning "i-1" to "previous tick"
         int last_tick = tick.last; 
         int prev_tick = tickPrev.last;

         if(last_tick!=prev_tick); // if last tick != previous tick, then
           {
            if(last_tick>prev_tick) // if last...
              {
               tickcounter=tickcounter+1;
              }
            else if(last_tick>prev_tick)
              {
               tickcounter=tickcounter-1;
              }
           }
           if(i=copied_ticks-1)
           {
            tickcounter=0;
           }
        }

Am I missing something ? Is this kind of approach "wrong" or inefficient in computing time ?

I'd print ALL of the code in real time, IF the markets were open now, but, since that cannot be done, id appreciate some inputs!


Thanks

Best Regards

 

Update:

I had some spare time today to debug / run the code while the market was open,  but I'm still not getting it right.

I realized that the For Loop was getting filled as soon as there were already 100 trades on the Symbol selected, and then, from there on, the values just kept adding up. I was unable to "reset" the counter every N ticks (N=1000) as I wanted to.

I was trying to print on the chart (comment) so I could follow the logic of the CopyTicks function, but I had very little time to do it and ended up without an answer.

Would anyone care to comment ?


I modified the code to this attached below:

// /==================================================================\
// | Tick counter block                                               |
// \==================================================================/

   MqlTick tick_array[]; //defining array to copy ticks to

   int copied_ticks=CopyTicks(_Symbol,tick_array,COPY_TICKS_TRADE,0,1000);
   int tickcounter; // defining tickcounter as integer

   if(copied_ticks>0) // if array is not empty 
    {
      string comment = "# Last Tick   # Tick Counter";
      
         MqlTick tick;
         SymbolInfoTick(Symbol(),tick); 
         // tick index 0 is the oldest one in the array.
         MqlTick tickPrev = tick_array[copied_ticks-2]; 
         
         int last_tick = tick.last; // "last tick" double from 0 index
         int prev_tick = tickPrev.last; // "last tick" double from "prev" index

            if(last_tick>prev_tick) // if newest "last tick" > previous "last tick"
              {
               tickcounter=tickcounter+1; 
              }
            else if(last_tick>prev_tick)
              {
               tickcounter=tickcounter-1;
              }
              
         printf(last_tick, prev_tick);
         
         string tick_string=StringFormat(" %G / %G / %G", 
                                          prev_tick,
                                          last_tick, 
                                          tickcounter);
         comment = tick_string ; 
         Comment(comment);
    }
   else // report an error that occurred when receiving ticks
    {
      Comment("Ticks could not be loaded. GetLastError()=",GetLastError());
    }
    
// /==================================================================\
// | Tick counter block                                               |
// \==================================================================/
    
 
Do you intend to use the code to count previous ticks or count ticks in real time?
 
Enrico Lambino:
Do you intend to use the code to count previous ticks or count ticks in real time?

Hi there Enrico,

I intend to count them in real time, like, i want to know what was the "direction" of the last N ticks, but i want to know that in real time so i can use this input to bias my decision on buying or selling some symbol.

I managed to do it here today when i had some spare time while the market was still running. Thanks!

 
Eduardo Gonzatti:

Hi there Enrico,

I intend to count them in real time, like, i want to know what was the "direction" of the last N ticks, but i want to know that in real time so i can use this input to bias my decision on buying or selling some symbol.

I managed to do it here today when i had some spare time while the market was still running. Thanks!

1. I think the operator for the second condition should be <, not >. The current code would always increment the tick counter if the tick values are not the same.
if(last_tick>prev_tick) // if newest "last tick" > previous "last tick"
{
   tickcounter=tickcounter+1; 
}
else if(last_tick<prev_tick)
{
   tickcounter=tickcounter-1;
}


2. The variable last on MQLTick, as far as I know, is used to get the price of the last deal since the start of the terminal. You should use either Bid or Ask when comparing tick prices.

int last_tick = tick.Bid; // "last tick" double from 0 index
int prev_tick = tickPrev.Bid; // "last tick" double from "prev" index


3. You should make a comparison for each tick and the one that came before it in a loop.


4. The tick at index 0 using CopyTicks is the oldest tick. In your current code, you are comparing the current tick to the second to the oldest tick on the tick array:

SymbolInfoTick(Symbol(),tick); 
// tick index 0 is the oldest one in the array.
MqlTick tickPrev = tick_array[copied_ticks-2];

So, if you are to compare the newest (current) tick with the tick that came before it:

MqlTick tickPrev = tick_array[copied_ticks-1]; 
MqlTick tick = tick_array[copied_ticks-2]; 

Here is the loop (I have not tested this so just correct if there are any errors):

for (int i=copied_ticks-1;i>0;i--)
{   
   MqlTick tickPrev = tick_array[i]; 
   MqlTick tick = tick_array[i-1]; 

   
   if(last_tick>prev_tick)
   {
      tickcounter=tickcounter+1; 
   }
   else if(last_tick<prev_tick)
   {
      tickcounter=tickcounter-1;
   }
}
 
Enrico Lambino:
1. I think the operator for the second condition should be <, not >. The current code would always increment the tick counter if the tick values are not the same.


2. The variable last on MQLTick, as far as I know, is used to get the price of the last deal since the start of the terminal. You should use either Bid or Ask when comparing tick prices.


3. You should make a comparison for each tick and the one that came before it in a loop.


4. The tick at index 0 using CopyTicks is the oldest tick. In your current code, you are comparing the current tick to the second to the oldest tick on the tick array:

So, if you are to compare the newest (current) tick with the tick that came before it:

Here is the loop (I have not tested this so just correct if there are any errors):

Hi there, thanks for the reply.

What I did was this here, I had not posted before:

   static int old_tick; // 
   static int tickcounter; // counter
   static int contador; // integer 
   string comment; // string 

   MqlTick tick_array[1]; // array 
   ArraySetAsSeries(tick_array,true); // array index 0 ~> newest
   MqlTick tick = tick_array[0]; // "0" == most recent
         
     if(old_tick != tick_last  ) // 
       {        
      if(tick_last  > old_tick) // 
        {
         tickcounter=tickcounter+1; // 
         contador = contador +1;
        }
      else if(tick_last < old_tick) // 
        {
         tickcounter=tickcounter-1; // 
         contador = contador +1 ;
        }
       } 
      else
        { 
         tickcounter=tickcounter;
        }                
      string tick_string=StringFormat(" %G / %G / %G / %G ", 
                                       old_tick,tick_last, 
                                       tickcounter,contador);
      comment = tick_string ; 
      Comment(comment);
      old_tick=tick_last; // 
      
      if(contador == 1000)
        {
         tickcounter=0;
         contador=0;
        }

what im still trying to do is to "create" an N elements Array so i can sum all of the elements inside this array and have an "sum output" that will work as a moving window of the array sum.


here's my idea so far, not working very well.. but..


   static int old_tick; // 
   static int tickcounter; // 
   int counter_array[]; // 
   int tickcounterSum; 
   string comment; //
   
   MqlTick tick_array[1]; // array de duas unidades, 0 e 1
   MqlTick tick = tick_array[0]; // "0" == most recent
         
     if(old_tick != tick_last  ) // 
       {        
      if(tick_last > old_tick) // 
        {
         tickcounter=1; // counter + 1
        }
      else if(tick_last < old_tick) // 
        {
         tickcounter=-1; // counter - 1
        }
       }
      else
       {
        tickcounter=0;
       }               
      old_tick=tick_last; //
     
      ArrayResize(counter_array,100);
      // fills up the array w last 100 tickcounters 

      for( int iArray = ArraySize(counter_array)-1; iArray >= 0 ; iArray--)
      {
       // add up last "tickcounter" element to the array, starting on the counter "iArray"
       ArrayFill(counter_array,iArray,1,tickcounter); // probably wrong, right?
       // at each iteration, it should sum all the elements inside the array
       tickcounterSum+=counter_array[iArray];
      }
      
      string tick_string = StringFormat(" %g / %g ",tickcounterSum, tickcounter);
      comment = tick_string ; 
      Comment(comment);
      
 

ok, for anyone that might be interested in this thread..

im printing everything here in the terminal so i can see whats going on with the "arrayfill" , since i just cant manage to understand great deal of documentation provided by the platform;

      ArrayFill(counter_array,0,1,tickcounter);     // from what i see, this here fills the array with "1" element, starting from the "0" element in it

      for( int i=0; i<ArraySize(counter_array); i++) // normal loop
      {
       printf("%g / %g / %g ",tickcounter,i,counter_array[i]);  // printing
      }

what happens is this:


first column : last tick ( 0 == equal to the previous tick)

2nd column: for "i"

3rd column: counter_array[i]


as you might guess, i have no idea of what is going on inside this array. what i did wanted to happen was:

every new information (tick direction as the "0" in the 1st column) would enter this array, erasing the oldest element inside it (array) so i would continuously have a "fresh", updated "last N ticks direction array"


i have defined the array as a [10] array, and im trying all sorts of things here in this printing loop i have so i can try to figure something out..

 

new update:

printing is still very messed up.. i cant seem to get this right..

   tick_last is the symbol last tick..
   old tick is a static..
 
     if(old_tick != tick_last  ) 
       {        
      if(tick_last > old_tick) 
        {
         tickcounter=1; 
         contador = contador +1;
        }
      else if(tick_last < old_tick) 
        {
         tickcounter=-1;
         contador = contador-1;
        }
       }
      else
       {
        tickcounter=0;
       }               
      old_tick=tick_last; 
      
// do i have to resize the array at every iteration?
      ArrayResize(counter_array,10);     
// should i "fill" the array from 0 to 9?
      ArrayFill(counter_array,0,9,tickcounter);
      
      for(int i=ArraySize(counter_array)-1; i>=0; i--)
      {              
       printf("[i0]=%d [i1]=%d [i2]=%d [i3]=%d [i4]=%d [i5]=%d [i6]=%d [i7]=%d [i8]=%d [i9]=%d",
       counter_array[0],counter_array[1],counter_array[2],counter_array[3],counter_array[4],
       counter_array[5],counter_array[6],counter_array[7],counter_array[8],counter_array[9]); 
      }

i guess ill have to go into specific classes like https://www.mql5.com/en/docs/standardlibrary/datastructures/carraydouble

if anyone has a better idea, feel free to chime in!

Documentation on MQL5: Standard Library / Classes of data / CArrayDouble
Documentation on MQL5: Standard Library / Classes of data / CArrayDouble
  • www.mql5.com
Standard Library / Classes of data / CArrayDouble - Reference on algorithmic/automated trading language for MetaTrader 5
 

ok, here is what i've come up with..

void OnTick()
{
   CArrayDouble *array_contador=new CArrayDouble;           // struct de Array
   double tick_last=SymbolInfoDouble(_Symbol,SYMBOL_LAST);  // last tick
   static int old_tick;                                     // prev tick 
   static int contador;                                     // integer counter ticks
   string comment;                                          // string    

     if(old_tick != tick_last)      //  tick != tick prev
       {        
      if(tick_last  > old_tick)     // tick > tick prev
        {
         tickcounter= 1;            // + 1
         contador = contador +1;    // @ #1, 0+1=1
        }
      else if(tick_last < old_tick) // if tick  < prev tick 
        {
         tickcounter= -1;           //  - 1
         contador = contador +1 ;
        }
       }
      else if(old_tick == tick_last)// new tick , same value
       {
        tickcounter= 0;             // 0
        contador = contador+1;      //  new tick , contador++
       }
      
      if(contador <= 100)           // from 1 to 100, contador, "0 a 99" in array
       {
        // starts adding up "ticcounter" one by one in the array
        array_contador.Insert(tickcounter,contador-1); 
       }
       
      else if(contador > 100)                  // starting from #101
       {                                       // is #100 in array
                                               // array has "0 to 99", 100 elements
        array_contador.Delete(0);              // #101, deletes #0 in array
                                               // array now has 99 elements
                                               // shifts "1 to 99" to "0 to 98"
        for( int i = 1; i<100; i++)            // #101, i = 1, i<100, i++
         {                                     // de i=1 a i=99, step = 1
          array_contador.Shift(i,-1);          // shift 1~>0, i++, 2~>1, i++...99~>98
                                               // array[99] elements from 0 to 98
         }                                     // now, adds up the new element
        array_contador.Add(tickcounter);       // array[100], 0 to 99, 99~>tickcounter
                                               
        for(int j = 0; j<100; j++)             // loop in array from 0 to 99 
         {                                     // in order to sum all elements inside
          printf("j %d/ array %d",j, array_contador.At(j));
          RollingCounter+=array_contador[j];   // global var summing all elements 
         }
       }
       
      string tick_string=StringFormat(" %d / %d / %d / %d / %d", 
                                       old_tick,tick_last, 
                                       tickcounter,contador,RollingCounter);
      comment = tick_string ; 
      Comment(comment);
      old_tick=tick_last;        // prev tick static = new tick
}

when i do print elements from inside the array, all i get is some gigantic numbers "^90000"


am im doing something wrong in the array class ? thanks

 

i tried to copy  MQLtick ,but in different MT5 terminal ,the result is different .

the flags is 6 or 24 .

the volume is 0 or a very large number .

I think MQLtick is not a practical stucture .

 

Why just not create counter?

ulong counter;
double prev_bid;
double prev_ask;
...
void OnInit()
{
prev_bid=Bid;
preb_ask=Ask;
}
...
void OnTick()
{
if(prev_bid!=Bid || prev_ask!=Ask)
{
counter++;
prev_bid=Bid;
preb_ask=Ask;
}
}
Reason: