How to check if last three orders were in loss?

 

How to check if last three orders were in loss (any buy or sell order) in order history for the current symbol? and if last three orders are in loss, the variable "last_3_orders" should be set to "1" else set to "0". 

(Mql4 code)

int last_3_orders = 0;
string last;

for(int i=OrdersHistoryTotal()-1,i>=0,i--)
 {
   OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);
   if(OrderSymbol()==Symbol())
    {
       //for buy order
       if(OrderType()==OP_BUY && OrderProfit()>0) last="profit";
       if(OrderType()==OP_BUY && OrderProfit()<0) last="loss";
       break; 
    }
 }
 

Something like :

   int count=0,countInLoss=0;
   int last_3_orders=0;

   for(int i=OrdersHistoryTotal()-1;i>=0;i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;
      if(OrderSymbol()==Symbol())
        {
         count++;
         if(OrderProfit()<0)
            countInLoss++;
         if(count==3)
            break;
        }
     }
//---
   last_3_orders=(countInLoss==3) ? 1 : 0;
Supposing the orders are correctly sorted (which is not always the case, so you could have to sort them).
 
#include <Arrays\List.mqh>

class Order : public CObject
{
   int ticket;
   datetime open_time;
   Order(int tick, datetime time):ticket(tick),open_time(time){}
   int Compare(const CObject *node,const int mode=0)const
   {
      /// sort open time descending
      Order *other = (Order*)node;
      if(this.open_time>other.open_time)return -1;
      if(this.open_time<other.open_time)return 1;
      return 0;
   }
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   CList order_list;
   for(int i=0;OrderSelect(i,SELECT_BY_POS);i++)
      order_list.Add(new Order(OrderTicket(),OrderOpenTime()))

   order_list.Sort(0);
   int loss_count=0;
   for(Order *order=order_list.GetFirstNode();order!=NULL;order=order.Next())
   {
      if(OrderSelect(order.ticket,SELECT_BY_TICKET) && OrderProfit()< 0.0)
         loss_count++;
      else break;
   }
   if(loss_count >= 3)
      Print("number of consecutive losses = ",loss_count);
   
  }
//+------------------------------------------------------------------+
 
nicholishen:

Hopefully, this code will not need to be executed on each tick on a 10 years backtest, I am curious to see how much time it's slower. 

  • Why do you need all orders when the OP want only current symbol orders ? 
  • What is the meaning of '0' in Sort() function ?
  • Why do you need 2 loops, each time checking OrderSelect() ?
  • Why are you "breaking" in your second loop if OrderSelect() is false ?
  • The sorting should be done by OrderCloseTime, don't you think ?
  • Do you know when the orders list is not sorted (so when we need to sort it by code) ?

I added this to my favorites, as a perfect example of a bad OOP usage. Have fun.

 
Alain Verleyen:

Hopefully, this code will not need to be executed on each tick on a 10 years backtest, I am curious to see how much time it's slower. 

  • Why do you need all orders when the OP want only current symbol orders ? 
  • What is the meaning of '0' in Sort() function ?
  • Why do you need 2 loops, each time checking OrderSelect() ?
  • Why are you "breaking" in your second loop if OrderSelect() is false ?
  • The sorting should be done by OrderCloseTime, don't you think ?
  • Do you know when the orders list is not sorted (so when we need to sort it by code) ?

I added this to my favorites, as a perfect example of a bad OOP usage. Have fun.


This is a basic example of how to implement a derived class that overrides CObject in order to add it to a list for sorting. OP is responsible for conforming the code to his needs, so if OP only wants current symbol then OP needs to code it that way not me, obviously. Furthermore, as whoeder states it is not guaranteed that your orders are sorted, and as we all know it is dangerous to assume anything when it comes to MT. 

  1. He can program however he wants. This was just an example.
  2. List, unfortunately, does not specify a default param. It should but it doesn't.
  3. The first loop adds all orders to the list and the second loop works with the List.
  4. If orderselect is false then you got problems with your code, no point in continuing loop. 
  5. Again, that is up to OP and if he desires to categorize the order of his trades by close time, he better damn well implement his own sorting method, such as this... or other.
  6. Mql history pool is generally sorted by open time, but not always guaranteed. 
There are other mistakes that you missed so your literal break-down of my code is also missing the fact that I didn't use OrdersHistoryTotal... but then again I whipped this up in no time and was not intended as production code. If you think this is a bad example of OOP then I'm afraid you don't really understand the point of OOP. Missing logic in an example snippet != poor OOP. In fact this is an excellent example of OOP using the std lib to easily solve the most widespread issue of how to programmatically sort orders by x category. 

 
nicholishen:

This is a basic example of how to implement a derived class that overrides CObject in order to add it to a list for sorting. OP is responsible for conforming the code to his needs, so if OP only wants current symbol then OP needs to code it that way not me, obviously. Furthermore, as whoeder states it is not guaranteed that your orders are sorted, and as we all know it is dangerous to assume anything when it comes to MT. 

There are other mistakes that you missed so your literal break-down of my code is also missing the fact that I didn't use OrdersHistoryTotal... but then again I whipped this up in no time and was not intended as production code. If you think this is a bad example of OOP then I'm afraid you don't really understand the point of OOP. Missing logic in an example snippet != poor OOP. In fact this is an excellent example of OOP using the std lib to easily solve the most widespread issue of how to programmatically sort orders by x category. 

Thanks for your answer. It confirms my initial opinion. Your code is full of bugs, is slower (than a good code, using OOP or not) and doesn't answer the OP question, but of course you are thinking it's me who don't understand something.

You are answering to a person, who had a specific question, do you care about this ? I showed you several bugs, according to what OP wants, and your answer is "the OP just have to fix that", seriously ?

It's slower than a non OOP version, or a good OOP version, do I have to prove it ? 

Why is it bad OOP example ? Because it's inefficient. The OP is most probably using the code in an EA, most of the time people want to backtest their EA, often using every tick, so efficiency is a must. Even on a live chart it's always better to have faster code. 

OOP is a whole, it's not only re-usability. And even on re-usability, your code is not easily re-usable following my standards. Is it easy to maintain, an other advantage of OOP ? not really, though it's small code so this not so obvious to judge on this case, so could be a matter of taste.

If you want to provide an example of CList usage, than say it, nobody can read your mind. If you want to provide some bugs hunting, they say it nobody can read your mind.

  1. He can program however he wants. This was just an example. Then say it, nobody can read your mind.
  2. List, unfortunately, does not specify a default param. It should but it doesn't. Ok, but you didn't answer the question.
  3. The first loop adds all orders to the list and the second loop works with the List. The question was why 2 loops, not what are doing the loops ? it's inefficientand useless.
  4. If orderselect is false then you got problems with your code, no point in continuing loop. Are you sure about that ? Why OrderSelect() returns false ? Any source ?
  5. Again, that is up to OP and if he desires to categorize the order of his trades by close time, he better damn well implement his own sorting method, such as this... or other. Yeah, we will say that.
  6. Mql history pool is generally sorted by open time, but not always guaranteed. Why is not guaranteed ?
And please avoid any personal attack, I criticized your code, nothing else. Don't assume what I understand or not, you will always be wrong anyway.
 
Alain Verleyen:

Thanks for your answer. It confirms my initial opinion. Your code is full of bugs, is slower (than a good code, using OOP or not) and doesn't answer the OP question, but of course you are thinking it's me who don't understand something.

You are answering to a person, who had a specific question, do you care about this ? I showed you several bugs, according to what OP wants, and your answer is "the OP just have to fix that", seriously ?

It's slower than a non OOP version, or a good OOP version, do I have to prove it ? 

Why is it bad OOP example ? Because it's inefficient. The OP is most probably using the code in an EA, most of the time people want to backtest their EA, often using every tick, so efficiency is a must. Even on a live chart it's always better to have faster code. 

OOP is a whole, it's not only re-usability. And even on re-usability, your code is not easily re-usable following my standards. Is it easy to maintain, an other advantage of OOP ? not really, though it's small code so this not so obvious to judge on this case, so could be a matter of taste.

If you want to provide an example of CList usage, than say it, nobody can read your mind. If you want to provide some bugs hunting, they say it nobody can read your mind.

And please avoid any personal attack, I criticized your code, nothing else. Don't assume what I understand or not, you will always be wrong anyway.
Ok, Alain, master of MQL, show me how you programmatically sort orders.
 
nicholishen:
Ok, Alain, master of MQL, show me how you programmatically sort orders.

You already sorted them. Why do you want me to do it ?

 
Alain Verleyen:

Thanks for your answer. It confirms my initial opinion. Your code is full of bugs, is slower (than a good code, using OOP or not) and doesn't answer the OP question, but of course you are thinking it's me who don't understand something.

You are answering to a person, who had a specific question, do you care about this ? I showed you several bugs, according to what OP wants, and your answer is "the OP just have to fix that", seriously ?

It's slower than a non OOP version, or a good OOP version, do I have to prove it ? 

Why is it bad OOP example ? Because it's inefficient. The OP is most probably using the code in an EA, most of the time people want to backtest their EA, often using every tick, so efficiency is a must. Even on a live chart it's always better to have faster code. 

OOP is a whole, it's not only re-usability. And even on re-usability, your code is not easily re-usable following my standards. Is it easy to maintain, an other advantage of OOP ? not really, though it's small code so this not so obvious to judge on this case, so could be a matter of taste.

If you want to provide an example of CList usage, than say it, nobody can read your mind. If you want to provide some bugs hunting, they say it nobody can read your mind.

And please avoid any personal attack, I criticized your code, nothing else. Don't assume what I understand or not, you will always be wrong anyway.

2. It should be implicit that Sort take an integer param to select a sorting mode. Haven't you worked with lists in MQL?

3. You have to add the objects to the list before you can sort them, again, haven't you worked with lists in MQL?

4. Orderselect would only return false if you fed in an invalid ticket. Like I said, bigger issues at play.

5. Do not assume history is ordered by date, it's not. 

 
Alain Verleyen:

You already sorted them. Why do you want me to do it ?


When did you sort them??

Ok, Alain, my specification is I want to know the sum of the profit on the last three orders sorted by close time not open time. What do you do? Go.

Reason: