Download MetaTrader 5

Comparing elements in an array

To add comments, please log in or register
snjage
57
snjage  

Hi everyone, 


I need to compare elements in an array with the last element. 


I am trying to compare a current swing high, with previous swing highs that occurred periods ago, and stored in an array.

This is in a bid to identify swing high points that occur on the same price zone. 

All the while I'm trying to avoid using many loops if possible. 

This is a snippet of my code :

for(int a=20;a>0; a--) 
    {
      if(iFractals(...) > 0.0)
       {
       ArrayResize(array, ArraySize(array)+1);
       array[ArraySize(array)-]=iFractals(....) ;
       } 
    } 


Now I would like to compare the last element of the array with the rest of the elements in the same array.


I also tried comparing by putting them on two separate arrays  and using array compare but I can't figure out how to compare individual elements. 


Please help..

Thanking you in advance. 

whroeder1
16572
whroeder1  

snjage:

Now I would like to compare the last element of the array with the rest of the elements in the same array.

I also tried comparing by putting them on two separate arrays  and using array compare but I can't figure out how to compare individual elements.

  1. Fractal returns zero if that shift isn't a fractal. Fill in your array only with non-zero values.
  2. Array Compare compares arrays, you want to compare elements.
    array[2] > array[0]
snjage
57
snjage  
whroeder1:
  1. Fractal returns zero if that shift isn't a fractal. Fill in your array only with non-zero values.
  2. Array Compare compares arrays, you want to compare elements.



 I just wanted to find an element in the array that is closer or equal to the new iFractals swing point to constitute a price zone. 

I have been trying the use of arraybsearch like below to no avail 

double val = 1.11557;
for(int a=20;a>0; a--) 
    {
      if(iFractals(...) > 0.0)
       {
       ArrayResize(array, ArraySize(array)+1);
       array[ArraySize(array)-]=iFractals(....) ;
       } 
    }
   ArraySort(array,WHOLE_ARRAY,0,MODE_ASCEND);
   int a=ArrayBsearch(array,val,WHOLE_ARRAY,0,MODE_ASCEND);
   Alert(High[a]);

This is not working as expected

Marco vd Heijden
Moderator
5956
Marco vd Heijden  

Of course you can not sort the array and then expect when you call

Alert(High[a]);

Expect it to return the value you want.

Sorting the array will mix up all the index numbers either descending or ascending, so after the sort function you can not use index numbers to call for data from original shifts from before you sorted the array.

In stead first find the highest value and compare it to see if its what you want.

If not, set it to zero and find the next highest value and compare it, and so on until there is nothing left to compare.

double val = 1.11557;
int index;// declare variable

int index=ArrayMaximum(array,WHOLE_ARRAY,0); // Now we have the highest value.

if(array[index]==val)
 {
  Alert("Match found at: ",array[index]," Index: ",index);// We found a match
 }

array[index]=0; // Set new zero value so that it will not be found again on the next run.

index=ArrayMaximum(array,WHOLE_ARRAY,0); // Now we have the second highest value.

if(array[index]==val)
 {
  Alert("Match found at: ",array[index]," Index: ",index);// We found a match
 }
 
// and etc or can be placed in a loop of course
snjage
57
snjage  
Marco vd Heijden:

Of course you can not sort the array and then expect when you call

Expect it to return the value you want.

Sorting the array will mix up all the index numbers either descending or ascending, so after the sort function you can not use index numbers to call for data from original shifts from before you sorted the array.

In stead first find the highest value and compare it to see if its what you want.

If not, set it to zero and find the next highest value and compare it, and so on until there is nothing left to compare.

Thank you now I fully understand about sorting an array and binary search. I was looking for a function that can match values and output the desired match without the use of too much code or loops. So I was thinking one of these array functions would help. All in all I am grateful for this explanation. I'll try to customize the above example to fit in my code 
snjage
57
snjage  
Marco vd Heijden:

Of course you can not sort the array and then expect when you call

Expect it to return the value you want.

Sorting the array will mix up all the index numbers either descending or ascending, so after the sort function you can not use index numbers to call for data from original shifts from before you sorted the array.

In stead first find the highest value and compare it to see if its what you want.

If not, set it to zero and find the next highest value and compare it, and so on until there is nothing left to compare.


I now found a way to work with binary search correctly.

Now the challenge I'm facing is to sort out an array of struct type.

How do I go about it? 

MqlRates rates[];
ArraySetAsSeries(rates,true);
int count=CopyRates(Symbol(),0,0,300,rates);
if(count>0)
{
  for(int i=0; i<count; i++)
        {
          ArraySort(rates,WHOLE_ARRAY,0,MODE_ASCEND);
          Alert(rates [i].high);
         }
}

This code won't work.

Please help.

whroeder1
16572
whroeder1  
snjage: Now the challenge I'm facing is to sort out an array of struct type.
Of course ArraySort won't work
  1. Use the CList class and derive a class (not a struct) from cObject.
  2. Use my Insertion sort. Sort multiple arrays - MQL4 and MetaTrader 4 - MQL4 programming forum
nicholishen
1090
nicholishen  
whroeder1:
Of course ArraySort won't work
  1. Use the CList class and derive a class (not a struct) from cObject.
  2. Use my Insertion sort. Sort multiple arrays - MQL4 and MetaTrader 4 - MQL4 programming forum

Here is something similar to what whroeder1 is talking about.

//+------------------------------------------------------------------+
//|                                                Compare_array.mq4 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property strict
#include <Arrays\ArrayObj.mqh>

class Fractal : public CObject
{
public:
   double   price;
   double   price_comp;
   int      f_mode;
   datetime time;
   Fractal( double price_compare,
            double price_of_fractal,
            int   fractal_mode,
            datetime fractal_time):
            price_comp(price_compare),
            price(price_of_fractal),
            time(fractal_time),
            f_mode(fractal_mode)
            {}
   double   Diff() const 
   { 
      int dig = (int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);
      return NormalizeDouble(MathAbs(price_comp - price),dig);
   }
   int      Compare(const CObject *node,const int mode=0)const
   {
      Fractal *other = (Fractal*)node;
      if( this.Diff() > other.Diff())
         return 1;
      if( this.Diff() < other.Diff())
         return -1;
      return 0;
   }
}; 

class FractalVector : public CArrayObj
{
public:
   void Add(double price_compare,
            double price_of_fractal,
            int fractal_mode,
            datetime fractal_time)
   {
      CArrayObj::Add(new Fractal(price_compare,price_of_fractal,fractal_mode,fractal_time));
   }
   Fractal* operator[](const int i)const{return (Fractal*)At(i);}
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
FractalVector v;
double comp_price = 0.0;

void OnStart()
{
   GetFractalData();
   v.Sort();
   int dig = (int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);
   Print("Comparison price = ",string(comp_price));
   for(int i=0;i<v.Total() && i < 10;i++)
   {
      string out = "index["+string(i)+"] ";
      out+= string(v[i].time)+ " | ";
      out+= string(v[i].price)+" ";
      out+= Mode(v[i].f_mode)+" | ";
      out+= "Diff = "+DoubleToString(v[i].Diff(),dig);
      Print(out); 
   }   
}
//+------------------------------------------------------------------+

void GetFractalData()
{
   MqlRates r[];
   ArraySetAsSeries(r,true);
   int total = CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),r);
   
   //double comp_price = 0.0;
   for(int i=0;i<total;i++)
   {
      double upper = iFractals(Symbol(),Period(),MODE_UPPER,i);
      double lower = iFractals(Symbol(),Period(),MODE_LOWER,i);
      if(upper != 0.0 && upper != NULL && upper != EMPTY_VALUE)
      {
         if(v.Total() == 0)
            comp_price = upper;
         v.Add(comp_price,upper,MODE_UPPER,r[i].time);    
      } 
      if(lower != 0.0 && lower != NULL && lower != EMPTY_VALUE)
      {
         if(v.Total() == 0)
            comp_price = lower;
         v.Add(comp_price,lower,MODE_LOWER,r[i].time);    
      }  
   }
}

string Mode(int mode)
{
   if(mode == MODE_UPPER)
      return "MODE_UPPER";
   if(mode == MODE_LOWER)
      return "MODE_LOWER";
   return "";
}
snjage
57
snjage  
whroeder1:
Of course ArraySort won't work
  1. Use the CList class and derive a class (not a struct) from cObject.
  2. Use my Insertion sort. Sort multiple arrays - MQL4 and MetaTrader 4 - MQL4 programming forum

Wow..This seems overwhelming but i'm up for the task. Thank you whroeder1

snjage
57
snjage  
nicholishen:

Here is something similar to what whroeder1 is talking about.


Thank you. I will use your examples as i learn 

snjage
57
snjage  

Hi all,

Just to seek for a clarification on how arraybsearch works

In the event that a searched value is not found, Is it meant to return a nearest found value or does it return the nearest found value that is less in value than the searched value?

12
To add comments, please log in or register