MQL questions

User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: MQL questions

Post by gaheitman »

gaheitman wrote:I still like an EA for this. Perhaps with a script to enter the orders (assuming you can't program that logic as well) with paired MagicNumbers and the EA would just manage them as they appear.

George
Since this is a coding question, I thought it might be fun to evolve a simple OCO EA in the forum. Below is the beginning of code that might one day handle all your OCO needs.... :lol:

In a nutshell, all it does is this:
  • See if there are any open/pending orders for the current chart symbol
  • If there is one pending order, delete it
  • If there are two orders
    • If either is an open order, try to delete the other one
At this point, it ignores magic numbers.

It is, of course, completely untested. I thought we should agree on what it should do before testing. :D

Code: Select all

//+------------------------------------------------------------------+
//|                                                  OCO-Watcher.mq4 |
//|                                 Copyright © 2012, George Heitman |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, George Heitman"
#property link      "http://www.stevehopwoodforex.com/phpBB3/viewtopic.php?f=15&t=237"

int init()  {
   return(0);
}

int deinit()  {
   return(0);
}

int start()  {
  
//only check once per minute
   static int M1BarCount=0;
   if (M1BarCount == iBars(Symbol(),PERIOD_M1)) return(0);
   M1BarCount=iBars(Symbol(),PERIOD_M1);
  
//make array of all open/pending tickets  
   int total=OrdersTotal();
   if (total == 0) return(0);
  
   int OpenTickets[];                         //array to hold all our ticket numbers
   ArrayResize(OpenTickets, total);           //make it big enough to hold all of them
   ArrayInitialize(OpenTickets, 0);
   
   int i;                                     //i will iterate over all orders
   int cnt=0;                                 //cnt will hold the number of trades to manage
   for(i = 0; i < total; i++) {
      if(OrderSelect(i, SELECT_BY_POS,MODE_TRADES)) {
         //skip the ones that don't match our symbol and MN
         if(OrderSymbol() != Symbol()) continue;
//         if(OrderMagicNumber() != MagicNumber) continue; - gah let's ignore these for now
         OpenTickets[cnt] = OrderTicket(); //It's a match, save it to the array
         cnt++;
       }//if(OrderSelect(i, SELECT_BY_POS))
   }//for(i = 0; i < OrdersTotal(); i++)


//first case is easy, we didn't find any so return
   if (cnt==0) return;  
   
//second case is a bit of an open question.  what if we find just one?
//the code here will delete the order if it is a pending type.
   if (cnt==1) {
      if(OrderSelect(OpenTickets[0],SELECT_BY_TICKET)) {
         switch(OrderType())
            {
               case OP_SELL:
               case OP_BUY: break;
               case OP_SELLSTOP:
               case OP_BUYSTOP:
               case OP_SELLLIMIT:
               case OP_BUYLIMIT: OrderDelete(OrderTicket());
            }
       }
   }
   

//ok, here's the interesting one, we found two.  We find out
//the type of each, and if one is open, delete the other one
   int type1 = -1;
   int type2 = -1;
   if (cnt == 2) {
      if (OrderSelect(OpenTickets[0],SELECT_BY_TICKET))
         type1=OrderType();
      if (OrderSelect(OpenTickets[1],SELECT_BY_TICKET))
         type2=OrderType();

      //this is a test to make sure we set them correctly, if not, exit
      if (type1 == -1 || type2 == -1) return;  
      
      //we are lazy here and count on OrderDelete failing if the other 
      //trade is actually open
      if (type1 <= OP_SELL) OrderDelete(OpenTickets[1]);
      if (type2 <= OP_SELL) OrderDelete(OpenTickets[0]);
  }
       
  return(0);
}
George
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: MQL questions

Post by gaheitman »

garyfritz wrote:Ah, right: the short (USDJPY) canceled its buy properly, but the longs didn't cancel their sells. I should have seen that.

The BUY_STOP in the chart I posted had clearly converted to a BUY. I don't know why it didn't trigger the code to cancel the SELL_STOP. The code looks to be symmetric with the sell case that worked.

No, all the positions exited shortly after I posted.
Actually, it may be the call to IsTradeAllowed( ) at the end of the main loop. What I think that means is if any other script/ea is trading on that platform at the moment the function is called, the script will just end. I doubt it was what the original author intended. I think you should just delete the IsTradeAllowed() call from the conditional and see what we get tomorrow.

Were the arrows gone? That code would still have been called.

George
garyfritz

Re: MQL questions

Post by garyfritz »

Yes, I think the arrows were gone. I know they got deleted when I tested Alt-X.

I was wondering if it was a timing issue too. Seems unlikely to happen 2 out of 3 times, though.
garyfritz

Re: MQL questions

Post by garyfritz »

George, I know you don't have anything else to do :lol: but have you given this any more thought?

I used the OCO script for two trades yesterday. This time the long properly canceled its corresponding sell, but the short didn't cancel the corresponding buy! Which I think is opposite to what I saw before??

I'd like to get this working reliably, and ideally I'd like to see it in an EA. I have some enhancements I'd like to add but I can do that once we have a working EA.

If you get a moment...
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: MQL questions

Post by gaheitman »

garyfritz wrote:George, I know you don't have anything else to do :lol: but have you given this any more thought?

I used the OCO script for two trades yesterday. This time the long properly canceled its corresponding sell, but the short didn't cancel the corresponding buy! Which I think is opposite to what I saw before??

I'd like to get this working reliably, and ideally I'd like to see it in an EA. I have some enhancements I'd like to add but I can do that once we have a working EA.

If you get a moment...
OK, you talked me into it. Here is a version that doesn't care about MagicNumbers, it just looks for a buy and a sell on the same pair of whatever chart it is on.

It tells you what it is doing in the comment field.

You can temporarily stop monitoring by changing the extern StopMonitoring variable to false. If the program detects that there is an invalid pair it will turn off monitoring and send an alert. If it detects any open tickets, it closes all pendings.

I tried to have it just check every minute, but I didn't like the delay, so it checks every tick. We can add that back if you are certain one minute in between is enough. I can also write something to wait a specified number of milliseconds.

Test away, and let me know what you find. :D

George
You do not have the required permissions to view the files attached to this post.
garyfritz

Re: MQL questions

Post by garyfritz »

Thanks, George!

OK, so this EA waits for 2 orders to be placed (by something/someone else), then it manages those two. If I felt lazy and didn't want to place the orders manually, I imagine I could modify the OCO script you wrote before to create those orders, and just disable the order-monitoring part of the script. I'll give it a try.

Now I need to expand this to a full EA, which opens the orders for this beastie to manage. Would you recommend doing it in minimal style like you did here, or do I need to use the full Steve EA Shell to handle orders &etc properly?
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: MQL questions

Post by gaheitman »

garyfritz wrote:Thanks, George!

OK, so this EA waits for 2 orders to be placed (by something/someone else), then it manages those two. If I felt lazy and didn't want to place the orders manually, I imagine I could modify the OCO script you wrote before to create those orders, and just disable the order-monitoring part of the script. I'll give it a try.

Now I need to expand this to a full EA, which opens the orders for this beastie to manage. Would you recommend doing it in minimal style like you did here, or do I need to use the full Steve EA Shell to handle orders &etc properly?
As of now, we don't have the code to calculate whether to take a trade or not, that's all still coming from you. It would not be a big deal to modify what we have to allow you to enter a buy price and sell price for the two orders. It could place them for you so you wouldn't have to deal with the other script. Then you'd only have to drop the EA on a pair you intended to trade. It would do the rest.

What is the post-open management logic that you use?

George
garyfritz

Re: MQL questions

Post by garyfritz »

Almost none. I wait for it to hit the TP or SL, or close it if it hasn't hit either one by 4:30pm ET the next day. Never had any luck improving on it with intraday fussing so I just let it run.

The logic I use is pretty fully explained in this post. Only minor addition I can think of is that I want to specify a trading window. So e.g. I would still use the 5pmET - 5pmET H/L for my breakout prices, but I might not place the orders until 7pm ET. If the market exceeds the breakout prices before I place the orders, cancel trades for the day; otherwise place the orders at 7pm. Cancel the pending orders at 3am if they haven't been hit yet; if one or the other has been hit, then let the trade run to the TP/SL or until we close trades at 4:30pm ET.
Post Reply

Return to “Coders Hangout”