How to count how many currency pair(s) running with active order(s) - page 2

 
nicholishen:

negligible

My example is wrong.

 
fxsaber:

My example is wrong.

template<typename T>
int GetUniqueElements(T &array[])
{
   const int size = ArraySize(array);
   int sub = 0;
   ArraySort(array);
   for(int i=0; i<size-1; i++)
      for(int j=i+1;j<size;j++)
         if(array[i] == array[j])
            sub++;
         else
         {
            i = j -1;
            break;
         }
   return size - sub;  
}
 
nicholishen:

ArraySort return false for string[].

 
fxsaber:

ArraySort return false for string[].

Yup... just use the Set collection.. it's easy and fast.

 

Forum on trading, automated trading systems and testing trading strategies

How to count how many currency pair(s) running with active order(s)

nicholishen, 2018.02.05 21:46

template<typename T>
int GetUniqueElements(T &array[])
{
   const int size = ArraySize(array);
   int sub = 0;
   ArraySort(array);
   for(int i=0; i<size-1; i++)
      for(int j=i+1;j<size;j++)
         if(array[i] == array[j])
            sub++;
         else
         {
            i = j -1;
            break;
         }
   return size - sub;  
}

Alternative (not for string[])

template<typename T>
int GetUniqueElements(T &array[])
{
   const int size = ArraySize(array);
   int sub =  size && ArraySort(array) ? 1 : 0;

   for(int i=size - 2; i >= 0; i--)
      if(array[i] != array[i + 1])
         sub++;

   return (sub);  
}
 
fxsaber:

Alternative (not for string[])

Alternative(any data-type)

template<typename T>
int GetUniqueElements(T &array[])
{
   const int size = ArraySize(array);
   int indexes[];
   for(int i=0; i<size; i++)
   {
      bool found = false;
      for(int j=ArraySize(indexes)-1;j>=0;j--)
      {
         if(array[indexes[j]] == array[i])
         {
            found = true;
            break;
         }
      }   
      if(!found)
      {
         int index = ArrayResize(indexes, ArraySize(indexes) + 1) -1;
         indexes[index] = i;
      }
   }
   return ArraySize(indexes);
}
 
whroeder1:

There is no such positions total in MT4.

  1. The if is redundant. If total is zero the for loop does nothing.

    Simplify your condition: i <= n-1 is the same as i < n.

  2. V = V is redundant. Simplify your code: ++running_symbol_total;

  3. Of course your code just equals OrdersTotal. I gave you the answer at #1. Where is your code that does that.

Sorry,i thought i was in mt5 session.

 
nicholishen:

The easiest way is to use a set collection.... 


Thank you very much. its works nicely!

 
nicholishen: Yup... just use the Set collection.. it's easy and fast.

The Easy and fast was what I stated in #1

  1. Start with an empty array of symbols.
  2. For each order, find the symbol in your array of symbols. If you don't find it, it's a new symbol, add it to the array.
  3. After the loop, the answer is the size of the array.
Thus
#define INDEX uint // 0 based
#define COUNT uint // 1 based

/** Linear search an _array_ for a specific _value_. @returns INDEX
 * of the first element found with _value_ or _end_ if not found.          */
template<typename Ti1, typename Ti2>
INDEX      find(const Ti1& inp[], INDEX iBeg, INDEX iEnd,
                       const Ti2& value){
   while(iBeg != iEnd && !(inp[iBeg] == value) )   ++iBeg;
   return iBeg;
}
COUNT count_open_symbols(void){
   string symbols[];    COUNT n=0;
   for(int iPos=OrdersTotal()-1; iPos >= 0; --iPos)
      if(OrderSelect(iPos, SELECT_BY_POS)
      && find(symbols, 0, n) == n){
         ArrayResize(symbols, n+1);
         symbols[n] = OrderSymbol();
         ++n;
   }  }
   return n;
}


 
whroeder1:

The Easy and fast was what I stated in #1

  1. Start with an empty array of symbols.
  2. For each order, find the symbol in your array of symbols. If you don't find it, it's a new symbol, add it to the array.
  3. After the loop, the answer is the size of the array.
Thus


Hello Mr Whroeder,

Thanks for all you do, and thank you for sharing your code snippet. Unfortunately I'm not able to compile your example (4 errors). Also, I do have some questions for which I hoped you could provide some clarity. First, would you mind explaining the difference between your method and the one that nicholishen proposed? It seems easier to me to use CArrayString in this context. Is there a material difference in your code?

This is my adaptation of nicholishen's example~

int CountOpenSymbols()
  {
   CArrayString symbols;
   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS) && symbols.SearchLinear(OrderSymbol()) < 0)
         if(!symbols.Add(OrderSymbol()))
            Print("error = ",_LastError);
   return(symbols.Total());
  }

I'm very confused with some patterns in your example. Would you mind sharing your explanation?

#define INDEX uint // 0 based
#define COUNT uint // 1 based

/** Linear search an _array_ for a specific _value_. @returns INDEX
* of the first element found with _value_ or _end_ if not found.          */
template <typename Ti1, typename Ti2>
INDEX find(const Ti1 &inp[], INDEX iBeg, INDEX iEnd, const Ti2 &value)
{
  while (iBeg != iEnd && !(inp[iBeg] == value))
     ++iBeg;
  return iBeg;
}

COUNT count_open_symbols(void)
{
  string symbols[];
  COUNT n = 0;
  for (int iPos = OrdersTotal() - 1; iPos >= 0; --iPos)
  {
     if (OrderSelect(iPos, SELECT_BY_POS) && find(symbols, 0, n) == n)
     {
        ArrayResize(symbols, n + 1);
        symbols[n] = OrderSymbol();
        ++n;
     }
  }
  return n;
}

  1. What is the purpose for this code? It's very confusing because it looks like the MQL convention used for enum return type. 

#define INDEX uint // 0 based
#define COUNT uint // 1 based

2. Why use a separated funtion instead of a nested for loop?


Best regards, 

SB

Reason: