Duplicate values in Dynamic Array after ArraySort()

To add comments, please log in or register
Mike Tanton
535
Mike Tanton  

Hi Guys - I'm struggling with something that should be really simple and I'm not sure what I am doing wrong here.

I have 2 simple Dynamic Arrays. 

The first one stores a list of all my "Winning" (positive) trades and works fine after I sort them (MODE-DESCENDING):

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);
            }
   }

ArraySort(BestPositionArray,WHOLE_ARRAY,0,MODE_DESCEND);


...but then, the second Array that lists all my "Losing" trades gives me "Duplicate" values after a MODE-ASCENDING sort:

for(int i=NoTradesWorst-1; i>=0; i--)
   {
      if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
         && ((OrderProfit() + OrderSwap() + OrderCommission())) <= 0)
            {
             WorstPositionArray[i,0] = (OrderProfit() + OrderSwap() + OrderCommission());
             WorstPositionArray[i,1] = OrderTicket();
             WorstPositionArray[i,2] = OrderMagicNumber();
             ArraySort(WorstPositionArray,WHOLE_ARRAY,0,MODE_ASCEND);
            }
   }
ArraySort(WorstPositionArray,WHOLE_ARRAY,0,MODE_ASCEND);


I've tried ArraySetAsSeries() and can't seem to find anything in the Documentation. Can someone please point me in the right direction here or explain why I am having this problem.

Thanks...

Alain Verleyen
38855
Alain Verleyen  

What duplicate values ?

Why are you sorting inside the loop ?

Mike Tanton
535
Mike Tanton  
Alain Verleyen:

What duplicate values ?

Why are you sorting inside the loop ?

Hi Alain...

I've check the values in the Arrays and they are - Correct

What sent me on this tangent is that I convert the information from these Arrays into Objects (a small GUI on the main chart). Like this:


Looking at just the "Best" trades... 1. and 2. are both EURAUD.... but, if I put the Sort function inside the loop then it works fine...


...BUT... it does not matter what I do to the "Worst" trades....LMAO.....


Hehehhh... ok, so it must have something to do with the Object Labels... To get the Variables for the Object Labels I run this code:

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);

//--- Run Best Pair Calculations -------------------------------------------
if(NoTradesBest >=1)
   {
      for(int i=OrdersTotal()-1; i>=0; i--)
         {
            if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
               && OrderTicket() == BestPositionArray[0,1])
                  {
                   PairText = OrderSymbol();
                  }
         }
      
      Best1Pair = PairText;
      
      TFNumber = StringSubstr(DoubleToString(BestPositionArray[0,2]),0,2);
      Get_TimeFrame_Text();
      Best1TF = TFText;
      
      MANumber = StringSubstr(DoubleToString(BestPositionArray[0,2]),4,3);
      Get_TMA_Text();
      Best1MA = MAText;
   }

Which gives me the variables to use when creating the Object Labels...

   string BestPair1 = "Roxy_BestTrade_Pair1";

      ObjectCreate(0,BestPair1,OBJ_LABEL,0,0,0,0,0);
         ObjectSet(BestPair1,OBJPROP_CORNER,CORNER_LEFT_UPPER);
         ObjectSetInteger(0,BestPair1,OBJPROP_ANCHOR,ANCHOR_CENTER);
         ObjectSet(BestPair1,OBJPROP_XDISTANCE,65*ChartCoeff);         
         ObjectSet(BestPair1,OBJPROP_YDISTANCE,205*ChartCoeff); 
         ObjectSetInteger(0,BestPair1,OBJPROP_BACK,false);
         ObjectSetInteger(0,BestPair1,OBJPROP_ZORDER,100);
         ObjectSet(BestPair1,OBJPROP_HIDDEN,true);
         ObjectSetText(BestPair1,Best1Pair+"   "+"$'"+NormalizeDouble(B1,2),Text9,"Cambria",Gray);


   string BestValue1 = "Roxy_BestTrade_Value1";

      ObjectCreate(0,BestValue1,OBJ_LABEL,0,0,0,0,0);
         ObjectSet(BestValue1,OBJPROP_CORNER,CORNER_LEFT_UPPER);
         ObjectSetInteger(0,BestValue1,OBJPROP_ANCHOR,ANCHOR_CENTER);
         ObjectSet(BestValue1,OBJPROP_XDISTANCE,65*ChartCoeff);         
         ObjectSet(BestValue1,OBJPROP_YDISTANCE,220*ChartCoeff); 
         ObjectSetInteger(0,BestValue1,OBJPROP_BACK,false);
         ObjectSetInteger(0,BestValue1,OBJPROP_ZORDER,100);
         ObjectSet(BestValue1,OBJPROP_HIDDEN,true);
         ObjectSetText(BestValue1,Best1MA+"   "+Best1TF,Text9,"Cambria",Gray);

I'm thinking that deleting the Object Labels before Creating them again might work... but I remember years ago you told me that it was not necessary to "Delete" objects before creating them...

I'll play around with deleting the Labels... but if you do see anything wrong with the above code then please let me know and get me out of my misery....


Thanks

NOTE: There are currently only 2 trades open per Currency Pair (Symbol()) - 1 Long and 1 Short... so it is not possible for there to be 2 "winning" trades open on the same Symbol()...
Alain Verleyen
38855
Alain Verleyen  

It's hard to say anything useful from these snippets of code. I am wondering how is your array BestPositionArray is initialized and managed between each filling.

About the objects, you may need to call ChartRedraw() to update your chart.

Mike Tanton
535
Mike Tanton  
Alain Verleyen:

It's hard to say anything useful from these snippets of code. I am wondering how is your array BestPositionArray is initialized and managed between each filling.

About the objects, you may need to call ChartRedraw() to update your chart.

I just declare the Array... I did not realize I had to "Initialize" it... 

//+------------------------------------+
//| 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;
            }
   }
}




//+------------------------------------+
//| Populate Best Position Array       |
//+------------------------------------+
double B1,B2,B3,B4,B5,B6,B7,B8,B9,B10;
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);

//--- Run Best Pair Calculations -------------------------------------------
if(NoTradesBest >=1)
   {
      for(int i=OrdersTotal()-1; i>=0; i--)
         {
            if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
               && OrderTicket() == BestPositionArray[0,1])
                  {
                   PairText = OrderSymbol();
                  }
         }
      
      Best1Pair = PairText;
      
      TFNumber = StringSubstr(DoubleToString(BestPositionArray[0,2]),0,2);
      Get_TimeFrame_Text();
      Best1TF = TFText;
      
      MANumber = StringSubstr(DoubleToString(BestPositionArray[0,2]),4,3);
      Get_TMA_Text();
      Best1MA = MAText;
   }


//--- Run 2nd Best Pair Calculations -------------------------------------------
if(NoTradesBest >=2)
   {
      for(int i=OrdersTotal()-1; i>=0; i--)
         {
            if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
               && OrderTicket() == BestPositionArray[1,1])
                  {
                   PairText = OrderSymbol();
                  }
         }
      
      Best2Pair = PairText;
      
      TFNumber = StringSubstr(DoubleToString(BestPositionArray[1,2]),0,2);
      Get_TimeFrame_Text();
      Best2TF = TFText;
      
      MANumber = StringSubstr(DoubleToString(BestPositionArray[1,2]),4,3);
      Get_TMA_Text();
      Best2MA = MAText;
   }


//--- Run 3rd Best Pair Calculations -------------------------------------------
if(NoTradesBest >=3)
   {
      for(int i=OrdersTotal()-1; i>=0; i--)
         {
            if(   OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true
               && OrderTicket() == BestPositionArray[2,1])
                  {
                   PairText = OrderSymbol();
                  }
         }
      
      Best3Pair = PairText;
      
      TFNumber = StringSubstr(DoubleToString(BestPositionArray[2,2]),0,2);
      Get_TimeFrame_Text();
      Best3TF = TFText;
      
      MANumber = StringSubstr(DoubleToString(BestPositionArray[2,2]),4,3);
      Get_TMA_Text();
      Best3MA = MAText;
   }

if(NoTradesBest >= 1)   B1 = BestPositionArray[0,0];
if(NoTradesBest >= 2)   B2 = BestPositionArray[1,0];
if(NoTradesBest >= 3)   B3 = BestPositionArray[2,0];
if(NoTradesBest >= 4)   B4 = BestPositionArray[3,0];
if(NoTradesBest >= 5)   B5 = BestPositionArray[4,0];
if(NoTradesBest >= 6)   B6 = BestPositionArray[5,0];
if(NoTradesBest >= 7)   B7 = BestPositionArray[6,0];
if(NoTradesBest >= 8)   B8 = BestPositionArray[7,0];
if(NoTradesBest >= 9)   B9 = BestPositionArray[8,0];
if(NoTradesBest >= 10)  B10 = BestPositionArray[9,0];
}

ChartRedraw() did not help...

Alain Verleyen
38855
Alain Verleyen  
Mike Tanton:

I just declare the Array... I did not realize I had to "Initialize" it... 

ChartRedraw() did not help...

I don't see the problem.

If you need more help, please post the full code that I could compile and test.

Mike Tanton
535
Mike Tanton  

Thanks Alain....

Let me see if I can work it out... I don't want to waste your time on this.... I'm comfortable that the Arrays are giving the correct results... the GUI data is just superficial.... so, I'll be able to live with this glitch....

But thanks...

MikeT

Mike Tanton
535
Mike Tanton  

Ok, so... I'm still not 100% sure why the chart Object Labels were not keeping up with the code... but I solved the problem by simply "refreshing" the data after the functions in the code... so... it's now working...


I simply added this function...

//+--------------------------+
//| Refresh Roxy GUI         |
//+--------------------------+
void Refresh_Roxy_GUI()
{
ObjectSetText("Roxy_Today_PL_Value",DoubleToStr(TodayPL,2),Text14,"Cambria",Goldenrod);
ObjectSetText("Roxy_Today_%_Value",DoubleToStr(TodayPercent,1)+" %",Text12,"Cambria",Gray);

ObjectSetText("Roxy_BestTrade_Pair1",Best1Pair+"   "+"$'"+NormalizeDouble(B1,2),Text9,"Cambria",Gray);
ObjectSetText("Roxy_BestTrade_Pair2",Best2Pair+"   "+"$'"+NormalizeDouble(B2,2),Text9,"Cambria",Gray);
ObjectSetText("Roxy_BestTrade_Pair3",Best3Pair+"   "+"$'"+NormalizeDouble(B3,2),Text9,"Cambria",Gray);

ObjectSetText("Roxy_WorstTrade_Pair1",Worst1Pair+"   "+"$'"+NormalizeDouble(W1,2),Text9,"Cambria",Gray);
ObjectSetText("Roxy_WorstTrade_Pair2",Worst2Pair+"   "+"$'"+NormalizeDouble(W2,2),Text9,"Cambria",Gray);
ObjectSetText("Roxy_WorstTrade_Pair3",Worst3Pair+"   "+"$'"+NormalizeDouble(W3,2),Text9,"Cambria",Gray);
}

After the Array calculations...

Populate_Best_Position_Array();
Populate_Worst_Position_Array();

Refresh_Roxy_GUI();

Seems to be ok now....

Seng Joo Thio
1114
Seng Joo Thio  

I wonder... when you obtain a value for NoTradesBest here:

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;
            }
   }
}

and use it here:

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();
            }
   }
So if you have 10 orders in total and 5 winners - e.g. 0, 3, 4, 7, 9, and in your second loop, you're using OrderSelect() with 0 to 4, so you'll only find winners 0, 3 and 4, and skipped 7 and 9... isn't that a problem?


Mike Tanton
535
Mike Tanton  
Seng Joo Thio:

I wonder... when you obtain a value for NoTradesBest here:

and use it here:

So if you have 10 orders in total and 5 winners - e.g. 0, 3, 4, 7, 9, and in your second loop, you're using OrderSelect() with 0 to 4, so you'll only find winners 0, 3 and 4, and skipped 7 and 9... isn't that a problem?


Hi Seng... I think your math is a little bit wrong...

Using your eg. running the first loop will give NoTradesBest = 5 (5 winning trades ie. >$0)

Running the second loop using NoTradesBest  is still equal to 5 (5 winning trades ie. >$0)... but,

I need to run the "first" loop to determine how many positive trades there are... because this determines the size of the Dynamic Array  BestPositionArray[][3] - which is used in the 2nd loop

If that makes any sense to you...

Alain Verleyen
38855
Alain Verleyen  
Mike Tanton:

Hi Seng... I think your math is a little bit wrong...

Using your eg. running the first loop will give NoTradesBest = 5 (5 winning trades ie. >$0)

Running the second loop using NoTradesBest  is still equal to 5 (5 winning trades ie. >$0)... but,

I need to run the "first" loop to determine how many positive trades there are... because this determines the size of the Dynamic Array  BestPositionArray[][3] - which is used in the 2nd loop

If that makes any sense to you...

Seng is right, I don't know if it's the answer to your initial question, but it's a bug without a doubt.
12
To add comments, please log in or register