Median in timeseries array

 

Is there an easier way to find the median value in a time series array? Currently I copy the array, sort the copy and then select the median. Seems longwinded but couldn't find any standard functions to achieve the same thing. Anything better?

Thanks

V

 
If you don't copy the array then you can't sort it. If you don't sort it then you can't pinpoint the median value. pretty straightforward for me. If there was a standard functions then it would have to do it this way too AFAIK.
 
Viffer:

Is there an easier way to find the median value in a time series array? Currently I copy the array, sort the copy and then select the median. Seems longwinded but couldn't find any standard functions to achieve the same thing. Anything better?

Thanks

V

I understand what you are doing but I don't know HOW you do it.

Of course, I can research how to "copy the array" and how to "sort the copy".

But if you could explain how you do it, it would make the task a bit easier.

Thank you, Helmut

 
engcomp:

I understand what you are doing but I don't know HOW you do it.

Of course, I can research how to "copy the array" and how to "sort the copy".

But if you could explain how you do it, it would make the task a bit easier.

Thank you, Helmut

It's pretty easy if you use the standard functions:

https://docs.mql4.com/array

 
engcomp:

I understand what you are doing but I don't know HOW you do it.

Of course, I can research how to "copy the array" and how to "sort the copy".

But if you could explain how you do it, it would make the task a bit easier.

Thank you, Helmut


the copy and sort is straight forward but on reflection, the selection of median isn't. What I have done by simply dividing array length by 2 is good enough for me because I have enough elements to not worry about it, but my method is technically incorrect. if my array length was 5, I need to select element 2 but if it was 6, I need to find the mean of elements 2 & 3. To accurately find the median,imho, is quite convoluted and my method is technically inaccurate. Hence, I hoped there might be a function to help... by the looks of it there isn't.... I might try and build it. Anyway, abridged code below is my current status...

Thanks for the responses

V

   int   len=50;
   double   array[len],copy[len];
   static int   val;
   
   if (New_Bar)
      {
      val++;
      array[0]=val;
      ArrayCopy(copy,array,0,0,WHOLE_ARRAY);
      ArraySort(copy,WHOLE_ARRAY,0,MODE_DESCEND);
      median=copy[len/2];                                         
      for(i=len-1;i>=1;i--)
          {
          array[i]=array[i-1];
          }
      }
 
Viffer:

the copy and sort is straight forward but on reflection, the selection of median isn't. What I have done by simply dividing array length by 2 is good enough for me because I have enough elements to not worry about it, but my method is technically incorrect. if my array length was 5, I need to select element 2 but if it was 6, I need to find the mean of elements 2 & 3. To accurately find the median,imho, is quite convoluted and my method is technically inaccurate. Hence, I hoped there might be a function to help... by the looks of it there isn't.... I might try and build it. Anyway, abridged code below is my current status...

Thanks for the responses

V


Set len to be an odd number and you will always get correct median.
 

For sake of completion, here is the function I wrote...

V

[edited as per following discussion]

   double   ArrayMedian(double array[])
      {
      double median;
      double copy[];
      int len=ArraySize(array);
      ArrayResize(copy,len);
      ArrayCopy(copy,array,0,0,WHOLE_ARRAY);
      ArraySort(copy,WHOLE_ARRAY,0,MODE_DESCEND);
      if (len%2==0) // it's even
         {
         median=(copy[len/2]+copy[(len/2)-1])/2.0;
         }
      else        // it's odd
         {
         median=copy[len/2];
         }
      return(median);
      }          
 
Viffer:

For sake of completion, here is the function I wrote...

V

median=(copy[len/2]+copy[(len/2)+1])/2; in this case median may result in a value not present in the copy array. It will be a mere median value. If that's your intention you

can simply use ArrayMinimum() and ArrayMaximum() and find the median like that: median = (max+min)/2 without sorting the array. But if you want the find the median element

in the array use simply median = copy[len/2];

 
robofx.org:

median=(copy[len/2]+copy[(len/2)+1])/2; in this case median may result in a value not present in the copy array. It will be a mere median value. If that's your intention you

can simply use ArrayMinimum() and ArrayMaximum() and find the median like that: median = (max+min)/2 without sorting the array. But if you want the find the median element

in the array use simply median = copy[len/2];


The median is not (max+min)/2 except for the special case where the array has only 2 elements.

http://www.purplemath.com/modules/meanmode.htm


Median is explicitly described as the middle element in a rank-sorted series. If the series contains an even number of elements then the median is explicitly described as being the mean value of the middle two values.


 
1005phillip:


The median is not (max+min)/2 except for the special case where the array has only 2 elements.

http://www.purplemath.com/modules/meanmode.htm


Median is explicitly described as the middle element in a rank-sorted series. If the series contains an even number of elements then the median is explicitly described as being the mean value of the middle two values.


Right, sorry I mixed the terms.
 
Viffer:

For sake of completion, here is the function I wrote...

V


V make sure the typecast is double (not integer) when you compute the mean which require you to divide by 2.0 for those cases where the values indexed by len/2 and len/2-1 are integers.

median=(copy[len/2]+copy[(len/2)-1])/2.; //

Reason: