Median in timeseries array - page 2

 

Not sure I follow 100%... where len is even, division by 2 will always return an integer. When it's odd I need it to ignore the decimal and return just the integer. 5/2 = 2.5 as a double but 2 as an int. So len as int is best. Am I missing something?

 
Viffer:

Not sure I follow 100%... where len is even, division by 2 will always return an integer. When it's odd I need it to ignore the decimal and return just the integer. 5/2 = 2.5 as a double but 2 and an int. So len as int is best. Am I missing something?



The mean value of the two array values involves a division by 2, you need to make this a 2. (a double) instead of just 2 (an int) otherwise your mean value computation will fall into an integer typecast in the event that the array values themselves are integer values (even if the array itself is defined as a double).

mean = (Integer+Integer)/2 = (Integer+Integer)/Integer = Integer

mean = (Integer+Integer)/2. = (Integer+Integer)/Double = Double

You want your mean value, representing the median, to be a double and not typecast to an integer value.

 

Ah... I see what you mean. I read https://book.mql4.com/basics/expressions but understand from that that if median is declared as double (as it is in on the first line of the block), it will return a double even if doubles and intergers are mixed int the calculation...

double mean = (Integer+Integer)/2 = (Integer+Integer)/Integer = double


I might be about to have a "duh" moment but it hasn't slapped me in the face yet....your help in expediating the slap when it finally comes is gratefully received. So am I missing something?

V

(I'm off to watch opener on World Cup)

 

double mean = (Integer+Integer)/2 = (Integer+Integer)/Integer = double


Incorrect, the variable "mean" will be a double but the value it will be holding as computed by the integer/integer will be an integer value.

https://docs.mql4.com/basis/types/casting

Examples:

int    i = 1 / 2;     // no types casting, the result is 0
int    i = 1 / 2.0;   // the expression is cast to the double type, then is to the target type of int, the result is 0
double d = 1.0 / 2.0; // no types casting, the result is 0.5
double d = 1 / 2.0;   // the expression is cast to the double type that is the same as the target type, the result is 0.5    <- I want you to ensure this happens
double d = 1 / 2;     // the expression of the int type is cast to the target type of double, the result is 0.0              <- this one applies to you in your current calculation method
string s = 1.0 / 8;   // the expression is cast to the double type, then is to the target type of string, the result is "0.12500000" (the string containing 10 characters)
string s = NULL;      // the constant of type int is cast to the target type of string, the result is "0" (the string containing 1 character)
string s = "Ticket #"+12345; // the expression is cast to the string type that is the same as the target type, the result is "Ticket #12345"
 
double d = 1 / 2;     // the expression of the int type is cast to the target type of double, the result is 0.0 


Well I honestly didn't know that. thanks for pointing it out. I can see it now though int/int=int then cast to a double so 1/2=0 then cast to 0.0... all makes sense.

I think I ought to have another look through all my other code!

Thanks again

V

[I've updated the function code in case anyone is using it]

 
1005phillip:

Incorrect, the variable "mean" will be a double but the value it will be holding as computed by the integer/integer will be an integer value.

https://docs.mql4.com/basis/types/casting

Examples:

Amazing what one can learn just by eavesdropping the discussions on this forum.
 

Hello

I use Time Series to create new order with SL and TP based on median bar size from, may be it could help:

input double SL_Mult, // StopLoss Multiplier
             TP_Mult; // TakeProfit Multiplier

double ArrHigh[], ArrLow[], M_Point1, M_Point2, M_High, M_Low, MedianBarSize, MinStopLevel, SL, TP;
string symb=Symbol();
int TimeFrame=Period();

  {

   BarsCount = iBars(symb, Timeframe);

   CopyHigh(symb,TimeFrame,0,BarsCount,ArrHigh); // copy Time Series
   CopyLow(symb,TimeFrame,0,BarsCount,ArrLow);
  
   ArraySort(ArrHigh,WHOLE_ARRAY,0,MODE_ASCEND); //Sort Ascending
   ArraySort(ArrLow,WHOLE_ARRAY,0,MODE_ASCEND); 
  
   M_Point1 = MathFloor(BarsCount /2);    // First half end point
   M_Point2 = MathCeil((BarsCount /2)+1); // Second half start point

   M_High = (ArrHigh[M_Point1]+ArrHigh[M_Point2])/2; // Median High
   M_Low = (ArrLow[M_Point1]+ArrLow[M_Point2])/2; // Median Low
   MedianBarSize = NormalizeDouble((M_High-M_Low),Digits); // Median Bar Size
                
   MinStopLevel = MarketInfo(symb,MODE_STOPLEVEL);
                       
   SL=NormalizeDouble(OpeningPrice_Bid+MinStopLevel+(MedianBarSize*SL_Mult),Digits);  // SL based on Median Bar Size
   TP=NormalizeDouble(OpeningPrice_Ask-MinStopLevel-(MedianBarSize*TP_Mult),Digits);  // TP based on Median Bar Size  
   if (SL<=MinStopLevel) SL=MinStopLevel;
   if (TP<=MinStopLevel) TP=MinStopLevel;
}
 

To speed things up you can:

1) Add new values to already sorted array -> this way Copy() and Sort() get executed faster

2) Write a custom Sort() based on better/more suitable algorithm

Nothing else, median calculation requires a sorted array.

Also, as Viffer wrote, median is defined differently for odd and even size of array.

 

I have been programing a mean, because I find that the means indicator available for free are not exact in 

their calculations.  So , I have created some very different solution to the one you are showing here. 

My mql4 is almost finish. It has no bugs, but still not calculating the exact value of the mean. 

  My program has four parts to it. 

1. Fill the array

2. Sort the array

3. Find the mean if the period is odd number, or find the 2 center numbers and  operate. (a+b)/2

4. Graph the array.

 

THIS IS MY FUNCION 1) FILL THE ARRAY mediana1[]


double LLENAR_ARRAY(double Array)

{
  
   
  
  int x;
  for(x=0;x<Periodo;x++)   
       {                     

                 double a1= Close[x]; 

                 mediana1[x]=a1;        

                 
                             
                    
      }
                
               
return(Array);
}