Help with OCO

 

Hello, I looking on all forum and I don't find any good information on how to create an OCO.


I try to create my own OCO, but don't work. I want to insert in my EA.


Can you help me?

pgforex


//+------------------------------------------------------------------+
//|                                                          OCO.mq4 |
//|                                  Copyright © 2009, Pascal Gignac |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Pascal Gignac"


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   int sellStopOrder, buyStopOrder;
//----
   for(int i=OrdersTotal()-1;i>=0;i--)
   {
     OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
     
       if(OrderType() == OP_SELLSTOP && OrderSymbol() == Symbol())
       {
        sellStopOrder=OrderTicket();
       }
       if(OrderType() == OP_BUYSTOP && OrderSymbol() == Symbol())
       {
        buyStopOrder=OrderTicket();
       }
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
     {
       if(OrderType() == OP_BUY && OrderSymbol() == Symbol())
       {
        OrderDelete(sellStopOrder);
       }
       if(OrderType() == OP_SELL && OrderSymbol() == Symbol())
       {
        OrderDelete(buyStopOrder);
       }
     }
   }
   Comment("Sell Ticket:",sellStopOrder,"\nBuy Ticket:",buyStopOrder); 
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

Anybody can help me!


Thank's

 
pgforex:

Anybody can help me!

Let's say that there are only two orders. The order at #0 is your buy-stop, and it is still pending. The order at #1 is your sell-stop, which has been filled, turning it into OP_SELL. Your code starts at #1 and loops down to #0. On the first iteration, it will see that the sell order at #1 is filled, and will try to delete the ticket stored in buyStopOrder. However, that variable hasn't been populated yet.


You need to do two loops through the list of orders: the first to work out what's filled and what isn't, and the second to take action such as closing orders. Depending on the nature of your strategy you may be able to generalise and simplify your OCO rule to "delete all pending orders if the EA has one or more filled orders". That would go something like this:


   int i;
   int CountFilledOrders = 0;
   int CountPendingOrders = 0;

   // Count the number of pending and filled orders for this EA
   for (i = OrdersTotal() - 1; i >=0; i--) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MyMagicNumber) {
            switch (OrderType()) {
               case OP_BUY:
               case OP_SELL:
                  CountFilledOrders++;
                  break;
               default:
                  CountPendingOrders++;
                  break;        
            }
         }
      }
   }
   
   // If there are both pending and filled orders, delete the pending orders 
   if (CountFilledOrders > 0 && CountPendingOrders > 0) {
      for (i = OrdersTotal() - 1; i >=0; i--) {
         if (OrderSelect(i, SELECT_BY_POS)) {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MyMagicNumber) {
               switch (OrderType()) {
                  case OP_BUY:
                  case OP_SELL:
                     break;
                  default:
                     OrderDelete(OrderTicket());
                     break;        
               }
            }
         }
      }
   }
 

Thank you so much jjc. I don't know if it's work, the market are close.

If I don't use magic number in my EA, what happen with "MyMagicNumber".

I manualy open pending order. This EA set only TakeProfit, StopLoss and Breakeven.

Can I change "MyMagicNumber" with OrderMagicNumber()


Thank's

pgforex

 
pgforex:

I manualy open pending order. This EA set only TakeProfit, StopLoss and Breakeven.

Can I change "MyMagicNumber" with OrderMagicNumber()

If you're not running any EAs in addition to your manual trading, then you can simply take out the magic-number check. (i.e. leaving "if (OrderSymbol() == Symbol())"). If you are using EAs in addition to manual trading, then change the check to "OrderMagicNumber() == 0". This will delete pending orders which have been placed manually, leaving any orders placed by EAs.

 

Thank's jjc, I try this and I give you a feed back to the result.

 

Hello jjc, your code work very well. I think this code will help many people.


Thank's again!

pgforex

 

Hi guys,

I've just added this code to the bottom of my EA and backtested it.

It doesn't detect the pending orders, but is that because the back tester can't simulate the pending orders until it gets a feed from a broker?

 
Re4ctor:

Hi guys,

I've just added this code to the bottom of my EA and backtested it.

It doesn't detect the pending orders, but is that because the back tester can't simulate the pending orders until it gets a feed from a broker?

Nope, the Strategy Tester works just fine with pending orders.
 
JC:

Let's say that there are only two orders. The order at #0 is your buy-stop, and it is still pending. The order at #1 is your sell-stop, which has been filled, turning it into OP_SELL. Your code starts at #1 and loops down to #0. On the first iteration, it will see that the sell order at #1 is filled, and will try to delete the ticket stored in buyStopOrder. However, that variable hasn't been populated yet.


You need to do two loops through the list of orders: the first to work out what's filled and what isn't, and the second to take action such as closing orders. Depending on the nature of your strategy you may be able to generalise and simplify your OCO rule to "delete all pending orders if the EA has one or more filled orders". That would go something like this:


I had a similar problem. Your code helped me a lot. Thank you loads bro :)