How to get Highest, Lowest from a structure of array ?

 

Dear Members

I have a structure 

struct MqlIDXPrice
  {
    int     index;
    double  price;
  };

How can I get Lowest / Highest Price for 'n' bars and corresponding Index value ?

I tried ArraySort, but it does not work on structure.

Your guidance will be highly appreciated.

 

Hi Anil,

a structure is a set of elements of any type (except for the void type). Thus, the structure combines logically related data of different types

(copied from the MQL4 documentation :-)) That means, that you need an array (of structure elements) to hold the data and for searching or
sorting. First of all you need something like this:
   

MqlIDXPrice MyPrices[1000];

or

MqlIDXPrice MyPrices[];
...
ArrayResize(MyPrices, 1000);

Then you can do something like this:

        int HiPos, LowPos;
        double HiPrice = 0.0;
        double LowPrice = 99999999.0;

        for (int i = 0; i < ArraySize(MyPrices); i++)
        {
                if (MyPrices[i].price > HiPrice)
                {
                        HiPos = MyPrices[i].index;
                        HiPrice = MyPrices[i].price;
                }

                if (MyPrices[i].price < LowPrice)
                {
                        LowPos = MyPrices[i].index;
                        LowPrice = MyPrices[i].price;
                }
        }

I hope, this helps you

Best regards

 

Maybe you can use ArrayMaximum, but you would need to determine what struct is considered bigger in comparison to other:

struct MqlIDXPrice
{
   int     index;
   double  price;

   int Compare(const MqlIDXPrice&l, const MqlIDXPrice&r) const;
   
   bool operator>(const MqlIDXPrice&r) const { return Compare(this, r)==-1; }
   bool operator<(const MqlIDXPrice&r) const { return Compare(this, r)== 1; }
   bool operator==(const MqlIDXPrice&r) const { return Compare(this, r)== 0; }
};

int MqlIDXPrice::Compare(const MqlIDXPrice&l, const MqlIDXPrice&r) const
{
   if (l.price > r.price) return -1;

   if (l.price < r.price) return 1;

   if (l.index > r.index) return -1;

   if (l.index < r.index) return 1;
   
   return 0;
}

The operators above compare left struct ("this") with right struct, so  "this > right_struct" is true if "this" is bigger (and not equal) than "right_struct", so Compare returns -1


As I don't know how ArrayMaximum works internally, you may need to have other operators like >= or <=.

If it can't be used with custom structs, then just iterate the array and compare all elements, keeping the maximum

(Edit: ArrayMaximum would return the index of the max element in the array,  NOT the element itself)

 
Manuel Alejandro Cercos Perez: Maybe you can use ArrayMaximum,

OP can not, because that only works with numerical arrays. OP has an array of a structure.

 
Manuel Alejandro Cercos Perez:

Maybe you can use ArrayMaximum, but you would need to determine what struct is considered bigger in comparison to other:

The operators above compare left struct ("this") with right struct, so  "this > right_struct" is true if "this" is bigger (and not equal) than "right_struct", so Compare returns -1


As I don't know how ArrayMaximum works internally, you may need to have other operators like >= or <=.

If it can't be used with custom structs, then just iterate the array and compare all elements, keeping the maximum

(Edit: ArrayMaximum would return the index of the max element in the array,  NOT the element itself)

Thanks Manuel Alejandro

Seems there is no straight forward way to achieve this result.

 
Werner Klehr:

Hi Anil,

a structure is a set of elements of any type (except for the void type). Thus, the structure combines logically related data of different types

(copied from the MQL4 documentation :-)) That means, that you need an array (of structure elements) to hold the data and for searching or
sorting. First of all you need something like this:
   

or

Then you can do something like this:

I hope, this helps you

Best regards

Thanks Werner

Yeh I have defined MinorHigh[] of MqlIDXPrice structure type.

MinorHigh[] will contain index/price value of Minor Swing High from a ZigZag indicator.

It seems not possible to get Maximum out of MinorHigh[].price structure array. One possibility is to capture high prices into temporary tempHigh[], a simple array and use ArrayMaximum(tempHigh,10) but than I am lost as how to find its index value.

Will give it some more thoughts and try to find a way out.

 
William Roeder:

OP can not, because that only works with numerical arrays. OP has an array of a structure.

Yep, hadn't tested that, looks like he would need to remake it

At least, operators are still handy when using other data structures with templates (in my experience)

 
Anil Varma -:

Thanks Werner

Yeh I have defined MinorHigh[] of MqlIDXPrice structure type.

MinorHigh[] will contain index/price value of Minor Swing High from a ZigZag indicator.

It seems not possible to get Maximum out of MinorHigh[].price structure array. One possibility is to capture high prices into temporary tempHigh[], a simple array and use ArrayMaximum(tempHigh,10) but than I am lost as how to find its index value.

Will give it some more thoughts and try to find a way out.

Hi Anil,

maybe it is a good idea to first search through the array using a for loop (as in my example).
You can always look for a more optimal solution later

Best regards,

 
If you have a structure, use 2 statics inside and overload the operator=, record the data that's being assigned, let it store the index of the lowest and highest value in the static elements.

This works of course only if you use the structure for one array.

If you want this to be more versatile, you will need to create a class maintaining the array of structures itself. This class could be incooperated as a template class, getting specific with your structure.

Well, there are multiple ways of solving your issue.TThis would be one.
 
Dominik Egert:
If you have a structure, use 2 statics inside and overload the operator=, record the data that's being assigned, let it store the index of the lowest and highest value in the static elements.

This works of course only if you use the structure for one array.

If you want this to be more versatile, you will need to create a class maintaining the array of structures itself. This class could be incooperated as a template class, getting specific with your structure.

Well, there are multiple ways of solving your issue.TThis would be one.

@DominikEgert / @Werner Khehr / @Manuel Alejandro (Please guide me how can I refer a member, so they can see my reply in their inbox!!!)

Thanks a lot for all your suggestions. However currently I have resolved to following way, since it involved getting the Highest as well checking the order of highest for creating Fibo Expansion Points.

As the number of candles involved are few, this worked out well for me now. Any suggestion to improve or simplify this will be appreciated.

  //+----------------------------------------------------------------------------------------------------------+
  //| Calculate START Point Highest of MinorHigh[4], [3] or [2]
  //+----------------------------------------------------------------------------------------------------------+
    if((m_MinorHigh[4].index < 75) &&      // MinorHigh[4] is less than previous 75 bars
       (m_MinorHigh[4].price > m_MinorHigh[3].price) && (m_MinorHigh[4].price > m_MinorHigh[2].price))
      {
        IdxStart      = m_MinorHigh[4].index;
        FE.PriceStart = m_MinorHigh[4].price;
        FE.TimeStart  = iTime(m_WSymbol,m_WTimeFrame,IdxStart);
      }
    else if(m_MinorHigh[3].price > m_MinorHigh[2].price)
      {
        IdxStart      = m_MinorHigh[3].index;
        FE.PriceStart = m_MinorHigh[3].price;
        FE.TimeStart  = iTime(m_WSymbol,m_WTimeFrame,IdxStart);
      }
    else
      {
        IdxStart      = m_MinorHigh[2].index;
        FE.PriceStart = m_MinorHigh[2].price;
        FE.TimeStart  = iTime(m_WSymbol,m_WTimeFrame,IdxStart);
      }    
Reason: