Duplicate values in Dynamic Array after ArraySort() - page 2

 

I beg to disagree with you guys.... remember that I am filtering OrdersTotal() by using this condition:

&& ((OrderProfit() + OrderSwap() + OrderCommission())) > 0)

If there are 10 Orders... and 5 of them are positive ie. 5 "Winning" trades.... and I run the first loop

//+------------------------------------+
//| Number of Best Trades              |
//+------------------------------------+
void No_Best_Trades()
{
NoTradesBest=0;
for(int i=OrdersTotal()-1; i>=0; i--)
   {
      if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
         && ((OrderProfit() + OrderSwap() + OrderCommission())) > 0)
            {
             NoTradesBest += 1;
            }
   }
}

i = 10

NoTradesBest = 5

....when I run the second loop:

//+------------------------------------+
//| Populate Best Position Array       |
//+------------------------------------+
double BestPositionArray[][3];
void Populate_Best_Position_Array()
{
No_Best_Trades();

ArrayResize(BestPositionArray,NoTradesBest);

for(int i=NoTradesBest-1; i>=0; i--)
   {
      if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
         && ((OrderProfit() + OrderSwap() + OrderCommission())) >= 0)
            {
             BestPositionArray[i,0] = (OrderProfit() + OrderSwap() + OrderCommission());
             BestPositionArray[i,1] = OrderTicket();
             BestPositionArray[i,2] = OrderMagicNumber();
            }
   }

ArraySort(BestPositionArray,WHOLE_ARRAY,0,MODE_DESCEND);
}

i = 5

Yes...BUT, there are only 5 "winning" Trades/Orders (as calculated by the first loop).... so, I am not cutting off any positive "winning" trades... I'm still using the condition:

&& ((OrderProfit() + OrderSwap() + OrderCommission())) >= 0)

Well, I hope that is the bug you are referring too....

Out of the 10 Orders... with 5 being positive (> $0)  -  the BestPositionArray will (and is) populated with the data of 5 Orders.... all of which are positive

Anyways, thanks for at least making me think about it... If I'm being an idiot here and still missing it... then please let me know... but I think it's right - well, it is right if I check the array

 
Mike Tanton:

I beg to disagree with you guys.... remember that I am filtering OrdersTotal() by using this condition:

If there are 10 Orders... and 5 of them are positive ie. 5 "Winning" trades.... and I run the first loop

i = 10

NoTradesBest = 5

....when I run the second loop:

i = 5

Yes...BUT, there are only 5 "winning" Trades/Orders (as calculated by the first loop).... so, I am not cutting off any positive "winning" trades... I'm still using the condition:

Well, I hope that is the bug you are referring too....

Out of the 10 Orders... with 5 being positive (> $0)  -  the BestPositionArray will (and is) populated with the data of 5 Orders.... all of which are positive

Anyways, thanks for at least making me think about it... If I'm being an idiot here and still missing it... then please let me know... but I think it's right - well, it is right if I check the array

It can be or not depending on which orders are in profit, but most probably is it is NOT. If that's the 5 first (last as you count down), all will be ok. If not your array will not be correctly filled.

Example :

 index profit or loss
NoTradesBest
9
profit
 1
8
profit
 2
7
loss
 2
6
profit
 3
5
loss
 3
4
loss
 3
3
loss
 3
2
profit
 4
1
loss
 4
0
profit  5

You correctly count the "winners" = 5 in No_Best_Trades(), but then in Populate_Best_Position_Array() you loop from 4 to 0 : you are missing the orders indexed 9,8 and 6. You need to loop ALL the orders.

 

I've written a simple script (bottom) to illustrate the results you'll get given different sequence of orders (in this illustration I just use OrderProfitsn[] to represent that). Run it, and you'll see this result:

Test Case 1:   -1, 2, -4, 5, -2, 1, -3, 7, 9, -12,   MIKE's Bests:   5, 2, 0, 0, 0
Test Case 1:   -1, 2, -4, 5, -2, 1, -3, 7, 9, -12,   IDEAL's Bests:   9, 7, 5, 2, 1
------------------------------------------------------------
Test Case 2:   -1, -4, -2, -3, -12, 2, 5, 1, 7, 9,   MIKE's Bests:   0, 0, 0, 0, 0
Test Case 2:   -1, -4, -2, -3, -12, 2, 5, 1, 7, 9,   IDEAL's Bests:   9, 7, 5, 2, 1
------------------------------------------------------------
Test Case 3:   2, 5, 1, 7, 9, -1, -4, -2, -3, -12,   MIKE's Bests:   9, 7, 5, 2, 1
Test Case 3:   2, 5, 1, 7, 9, -1, -4, -2, -3, -12,   IDEAL's Bests:   9, 7, 5, 2, 1

Coded properly (the yellow ones), you get the right results always... but coded like yours, you'll only get right results when the inputs are already sequenced (by luck) in certain way.

Script:

#property strict

int NoTradesBest;
double BestPositionArray[];
double OrderProfits1[] = {-1,2,-4,5,-2,1,-3,7,9,-12};
double OrderProfits2[] = {-1,-4,-2,-3,-12,2,5,1,7,9};
double OrderProfits3[] = {2,5,1,7,9,-1,-4,-2,-3,-12};

void OnStart()
{
   Ideal_Populate_Best_Position_Array(OrderProfits3);
   Print ("Test Case 3:   ", ArrayToString(OrderProfits3), ",   IDEAL's Bests:   ", ArrayToString(BestPositionArray));
   Mike_Populate_Best_Position_Array(OrderProfits3);
   Print ("Test Case 3:   ", ArrayToString(OrderProfits3), ",   MIKE's Bests:   ", ArrayToString(BestPositionArray));
   
   Print ("------------------------------------------------------------");

   Ideal_Populate_Best_Position_Array(OrderProfits2);
   Print ("Test Case 2:   ", ArrayToString(OrderProfits2), ",   IDEAL's Bests:   ", ArrayToString(BestPositionArray));
   Mike_Populate_Best_Position_Array(OrderProfits2);
   Print ("Test Case 2:   ", ArrayToString(OrderProfits2), ",   MIKE's Bests:   ", ArrayToString(BestPositionArray));

   Print ("------------------------------------------------------------");

   Ideal_Populate_Best_Position_Array(OrderProfits1);
   Print ("Test Case 1:   ", ArrayToString(OrderProfits1), ",   IDEAL's Bests:   ", ArrayToString(BestPositionArray));
   Mike_Populate_Best_Position_Array(OrderProfits1);
   Print ("Test Case 1:   ", ArrayToString(OrderProfits1), ",   MIKE's Bests:   ", ArrayToString(BestPositionArray));
}

void No_Best_Trades(double &arr[])
{
   NoTradesBest = 0;
   for (int i=ArraySize(arr)-1; i>=0; i--)
      if (arr[i]>0)
         NoTradesBest += 1;
}

void Mike_Populate_Best_Position_Array(double &arr[])
{
   No_Best_Trades(arr);

   ArrayResize(BestPositionArray,NoTradesBest);
   ArrayInitialize(BestPositionArray,0);

   for (int i=NoTradesBest-1; i>=0; i--)
      if (arr[i]>0)  // This represents your OrderSelect(i,...) and profit checks
         BestPositionArray[i] = arr[i];
   
   ArraySort(BestPositionArray,WHOLE_ARRAY,0,MODE_DESCEND);
}

void Ideal_Populate_Best_Position_Array(double &arr[])
{
   No_Best_Trades(arr);

   ArrayResize(BestPositionArray,NoTradesBest);
   ArrayInitialize(BestPositionArray,0);

   int j = 0;
   for (int i=ArraySize(arr)-1; i>=0; i--)
      if (arr[i]>0)  // This represents your OrderSelect(i,...) and profit checks
         BestPositionArray[j++] = arr[i];
   
   ArraySort(BestPositionArray,WHOLE_ARRAY,0,MODE_DESCEND);
}

string ArrayToString(double &arr[])
{
   string Result = "";

   for (int i=0; i<ArraySize(arr); i++)
      Result = ((Result=="")?"":Result+", ")+string(arr[i]);

   return (Result);
}

Edit: "Ideal" solution for illustration only... actual/final solution requires additional safety checks :)

 
Thanks guys... I appreciate your input and code.