Need help counting consecutive profit orders and then resetting count after (x) amount of trades

 

I need help counting consecutive profit orders and then resetting count after (x) amount of trades.. So far I have:

int ProfitHistoryOrdersCount()
{
    int PosCnt = 0;
    int cnt = HistoryTotal();
    for (int i = cnt-1; i >=0; i--) {
               
        if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
        if (OrderSymbol() != Symbol()) continue;
        if (OrderMagicNumber() != Magic) continue;
       
                 
        int type = OrderType();
        if (type != OP_BUY && type != OP_SELL) continue;
                 
        if (OrderProfit() <= 0) continue;
        PosCnt++;
        }
    return (PosCnt);

}


The above code returns a value to: ProfitHistoryOrdersCount which will count the amount of consecutive profit trades. Now, I want to be able to reset this field to 0 after the count has been reached. Why? Because everytime this count is reached I would like to reset the lots which is handled in the order send part of the code. Currently, the lots will only be reset the first time the count is reached. I believe this is because the count continues increasing when I need it to reset afetr a fixed amount of profit trades.

I have tried many things including the code below, but no luck yet so looking for some help.

        {
         if(OrderProfit() >=0)PosCnt=0;
         if(OrderProfit() <=0)PosCnt++;
        }
        }
    return (PosCnt);
}
 

But . . . .

if (OrderProfit() <= 0) 

. . . it's a loss or BE, i.e. no profit, so why do you continue to the next order in the list ? you should return . . .

To reset and start your count again make a note of the first of your winning trades in your sequence (the most recent) . . after a reset only look for winning trades newer than this one.

 
RaptorUK:

But . . . .

. . . it's a loss or BE, i.e. no profit, so why do you continue to the next order in the list ? you should return . . .

To reset and start your count again make a note of the first of your winning trades in your sequence (the most recent) . . after a reset only look for winning trades newer than this one.

Could you please give me an example of the code that you would use? I dont quite understand what you mean. How would I reset after (x) amount of trades and start the count again? I do not know how to record the first winning trade in the most recent sequence no how to reference it to only look for newer winning trades. Could you possibly demonstrate by editing my code?

 

Well after an afternoon of trying and research I found the solution. It may not be the best solution, but it works for now until I find something better:

EDIT: This "fix" if you can call it that seems to reduce the orders count each time aswell, so perhaps it is NOT correct but I feel I am getting closer. Please if anyone can help me it would be greatly appreciated!

int ProfitHistoryOrdersCount() 
{
    int ProfitHistoryOrdersCount = 0;
    int cnt = OrdersHistoryTotal();
    for (int i = cnt-1; i >=0; i--) {
                
        if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
        //if (OrderSymbol() != Symbol()) continue;
        //if (OrderMagicNumber() != Magic) continue;
        
                  
        int type = OrderType();
        if (type != OP_BUY && type != OP_SELL) continue;
        if (ProfitHistoryOrdersCount > 5)
            ProfitHistoryOrdersCount = 0;
        if (OrderProfit() <= 0) continue;
        ProfitHistoryOrdersCount++;
        }
    return (ProfitHistoryOrdersCount);

}
 

You dont need those continues

int ProfitHistoryOrdersCount()
  {int ProfitHistoryOrdersCount = 0;
   int cnt = OrdersHistoryTotal();
   for (int i = cnt-1; i >=0; i--)
    {if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == true)
      {if (OrderSymbol() == Symbol())
        {if (OrderMagicNumber() == Magic)                          
          {if (OrderType() < 2)
            {if (ProfitHistoryOrdersCount > 5) ProfitHistoryOrdersCount = 0;
             if (OrderProfit() > 0) ProfitHistoryOrdersCount++;
    } } } } }
   return (ProfitHistoryOrdersCount);
  }
 
SDC:

You dont need those continues

And you don't need all those nested ifs
 
gangsta1:

Well after an afternoon of trying and research I found the solution. It may not be the best solution, but it works for now until I find something better:

EDIT: This "fix" if you can call it that seems to reduce the orders count each time aswell, so perhaps it is NOT correct but I feel I am getting closer. Please if anyone can help me it would be greatly appreciated!

I don't believe your code works . . . unless maybe I misunderstand what you are trying to do.

Imagine your last closed trade was a loss . . . then the number of consecutive wins you have is 0 . . . but your code will see that losing trade and the loop will move onto the next because of this . . .

if (OrderProfit() <= 0) continue;   //  if no profit move to next order in history
 
int ProfitHistoryOrdersCount(){
    int ProfitHistoryOrdersCount = 0;
    for (int i = OrdersHistoryTotal()-1; i >=0; i--) if(
        OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
    &&  OrderSymbol()      == Symbol()
    &&  OrderMagicNumber() == Magic
    &&  OrderType()        <= OP_SELL
    &&  OrderProfit()       > 0
    )   ProfitHistoryOrdersCount = (ProfitHistoryOrdersCount+1) % 6;
    return (ProfitHistoryOrdersCount);
}
  1. Don't need nested IFs
  2. Don't need those continues
  3. Don't need if (ProfitHistoryOrdersCount > 5)
  4. You'd never write if ( (x==y) == true ) so don't write if ( aBool == true )
 

Thanks guys, much appreciated and the solutions work. However, I need to also reset the count if the last order was a loss. It seems like it would be easy, but after a few hours of playing around I cannot get it to reset after a loss.

I tried this to no avail:

Cannot see why this would not work as it checks for a sell trade that had a loss and returns 0 to the count if this is the case. Am I missing something? Perhaps I have the brackets wrong or the return in the wrong place?

 int ProfitHistoryOrdersCount()
 {
 int ProfitHistoryOrdersCount = 0;
for (int i = OrdersHistoryTotal()-1; i >=0; i--)
 if

       (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
    &&  OrderSymbol()      == Symbol()
    &&  OrderMagicNumber() == 1
    &&  OrderType()        <= OP_SELL
    &&  OrderProfit()       > 0)
       
               ProfitHistoryOrdersCount = (ProfitHistoryOrdersCount+1) % 6;
    return (ProfitHistoryOrdersCount);
          
            
  if      (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
    &&  OrderSymbol()      == Symbol()
    &&  OrderMagicNumber() == 1
    &&  OrderType()        <= OP_SELL
    &&  OrderProfit()       < 0)
            
ProfitHistoryOrdersCount = 0;
    return (ProfitHistoryOrdersCount);
            
            }
 
gangsta1:

Thanks guys, much appreciated and the solutions work.

Sorry but they don't . . . . you need better test data and you will see they don't . . unless you have a different definition of consecutive ?
 
WHRoeder:
  1. Don't need nested IFs
  2. Don't need those continues
  3. Don't need if (ProfitHistoryOrdersCount > 5)
  4. You'd never write if ( (x==y) == true ) so don't write if ( aBool == true )
RaptorUK:
And you don't need all those nested ifs



I used nested Ifs instead of && because I read somewhere in this forum, nested if is more efficient in a for loop than && because the iteration will abort as soon as an if is not true but would go through all the &&'s before aborting if the whole statement is not true, is this not correct ?

I made a little test script to run two versions of that function 50,000 times each (to approximate 1 days worth of ticks) one version uses nested ifs the other uses &&.

After running the script several times the nested if version proved to be consistantly faster, so if you want faster strategy tester performance, do not use && in functions such as this. Use nested ifs.

Test Script:

//+------------------------------------------------------------------+
//|                                           ProfitHistoryTotal.mq4 |
//+------------------------------------------------------------------+


extern int Magic = 0;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   Alert("--------------------------------------------");
   int i = 0, starttime = 0;
   starttime = GetTickCount();
   for(i=0; i<50000; i++)
    {ProfitHistoryOrdersCount1();
    }
   Alert("Calculation time (&&) = ",GetTickCount()-starttime," milliseconds");
   
   starttime = GetTickCount();
   for(i=0; i<50000; i++)
    {ProfitHistoryOrdersCount2();
    }
   Alert("Calculation time (nested ifs) = ",GetTickCount()-starttime," milliseconds");

//----
   return(0);
  }
//+------------------------------------------------------------------+

int ProfitHistoryOrdersCount1()
  {
//----
   int ProfitHistoryOrdersCount = 0;
   for (int i = OrdersHistoryTotal()-1; i >=0; i--)
    {if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
     &&  OrderSymbol() == Symbol()
     &&  OrderMagicNumber() == Magic                          
     &&  OrderType() < 2
     &&  OrderProfit() > 0)
     ProfitHistoryOrdersCount = (ProfitHistoryOrdersCount+1) % 6;
    }
//----
   return(ProfitHistoryOrdersCount);
  }
//+------------------------------------------------------------------+

int ProfitHistoryOrdersCount2()
  {
//----  
   int ProfitHistoryOrdersCount = 0;
   for (int i = OrdersHistoryTotal()-1; i >=0; i--)
    {if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
      {if (OrderSymbol() == Symbol())
        {if (OrderMagicNumber() == Magic)                          
          {if (OrderType() < 2)
            {if (OrderProfit() > 0)
              {ProfitHistoryOrdersCount = (ProfitHistoryOrdersCount+1) % 6;
    } } } } } }
//----
   return(ProfitHistoryOrdersCount);
  }
//+------------------------------------------------------------------+
Reason: