Running EA on several charts without interference, maybe SelectOrder()? - page 2

 

Thanks, hehe not much sleep or time over with the little ones but managed to get 1,5 hours fiddling with MetaEditor while they were sleeping so lets see if I managed with you guys's help. 

 

Thanks for the help, think I might have figured it out but would be greatful if you could see what you think. 

(I would also love to open my mind and trade every asset from the same graph Roberto Jacobs, if that was what you meant. Just wanna keep it simple at first so I understand, babysteps.)

 

To clarify,

For now I have 3 EA's that do the exact same thing but are named differently and with the variation of the "int magic = 1", "int magic =2" and "int magic = 3" so that each EA gives the magic number to a certain position when it's opened.  

Problem was that one EA (asset 2) closed an open position of asset 1. So if EA asset 1 said open position and opened a position, EA asset 2 maybe said it was closing time/don't open order, and closed the first available open order in the trade terminal outside of it's own asset class.

 

Solution logic (yeah or nah?) 

Now with your help, I've done a for loop in the method "countOpenOrders" that I think returns the unique OrderTicket() number for the correct open asset-order for the running EA on the correct graph by using MagicNumber ("int magic" in my code").

If I've done the loop correctly then I should (I think) get the correct OrderTicket-number and I can then use that number and say close that particular order with OrderSelect(TicketNumber), haven't gotten to this part in my code yet.
Wehaa if this works :) 
Not sure if I should just post the method code or the whole code so will do both. What do you think, back to the drawing table or did I get it right? Also, I commented in the code. Honest_Knave could you help me understand? Really appreciate the help.

 

Code 

 int X;

int countOpenOrders()

{

   int Ticket=0;

   for(int i=OrdersTotal()-1; i>=0; i--)

     {

      if (!OrderSelect(i,SELECT_BY_POS))  continue;  //I don't fully understand this line

      //if (OrderSymbol() != _Symbol)       continue; //Is Symbol automatically the symbol of the chart the EA is running in?

      //Also, if I only have one open position per chart/asset this above line is obsolete right?

      if (OrderMagicNumber() != magic)    continue;

      if (OrderType() == OP_BUY){X = OrderTicket();} //This way I get the orderTicket if there is an open order with the correct magic number, thus knowing which order to close later?

      }

      return (X);

}


//--- input parameters
int X;
int countOpenOrders()
{
   int Ticket=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if (!OrderSelect(i,SELECT_BY_POS))  continue;  //I don't fully understand this line, please help.
      //if (OrderSymbol() != _Symbol)       continue; //Is Symbol automatically the symbol of the chart      the EA is running in? Don't fully understand.
      //Also, if I only have one open position per chart/asset this above line is obsolete right?
      if (OrderMagicNumber() != magic)    continue;
      if (OrderType() == OP_BUY){X = OrderTicket();} //This way I get the orderTicket if there is an open order with the correct magic number, thus knowing which order to close later?
      }
      return (X);
}



//Setting MagicNumer and Expert_ID, not sure if I need Expert_ID though.
int Expert_ID = 1;
int magic = 1;


//A bunch of different params for getting iMA-value
string symbol = NULL;
int timeFrame = 0;
int period = 2;
int period2 = 5;
int maShift = 0;
int lastBarShift = 0;
int antalOpenOrders;
double imaTest;
double imaTest2;

int order;
color Color = CLR_NONE;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
void init()
  {
    Alert("Function init startade");
  }
  
  
//+------------------------------------------------------------------+
//| start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//Calculating value of two different MA's
imaTest = iMA(symbol,timeFrame,period, maShift,MODE_SMA,PRICE_MEDIAN,lastBarShift);

imaTest2 = iMA(symbol,timeFrame,period2, maShift,MODE_SMA,PRICE_MEDIAN,lastBarShift);

antalOpenOrders = OrdersTotal();



//PS, this is currently a long only EA to keep it simple
//OPENING order criteria
if((imaTest-imaTest2) > 0 && (antalOpenOrders == 0))
{
   //Open new order
   OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Bid-200*Point, NULL,NULL, 1);
   Alert("Order opened for this particular asset");
}
else{Alert("No order opened");}




//CLOSING order critera,
//Here I will take the OrderTicket number and try to do an OrderSelect() with that ticketnumber and then say close.
}
  
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void deinit()
  {

      Alert("Function deinit startade");
  }
 

I'm not entirely clear on what you're trying to do, but we'll start with your questions on the code snippet:

if (!OrderSelect(i,SELECT_BY_POS))  continue;  //I don't fully understand this line

You must "select" an order before you can correctly use the functions OrderMagicNumber() and OrderType().

It could have been written this way if that helps you understand: 

if (OrderSelect(i,SELECT_BY_POS) == false)  continue;

"continue" means move to the next iteration of the loop (i.e. the next order)... not continue to the next line (a little counter-intuitive if you don't know).

if (OrderSymbol() != _Symbol)       continue; //Is Symbol automatically the symbol of the chart the EA is running in? Don't fully understand.

Yes, _Symbol is the symbol of the chart it is running on

//Also, if I only have one open position per chart/asset this above line is obsolete right?

 No, because this code is looping through every single open order in the terminal. That is why you need to do checks to find the orders you are interested in.

if (OrderType() == OP_BUY){X = OrderTicket();} //This way I get the orderTicket if there is an open order with the correct magic number, thus knowing which order to close later?

Generally speaking, it is better not to store information that you can find out again later when you need it. Coded correctly, it means you can recover from unexpected restarts etc.
 

 

Thanks Honest_knave, 

 Much clearer now,  

 

I also realized that I need to change my order opening position and use a loop to go through opening positions method and see if they are in the specif Asset Symbol. I will re-write some more (take away some) code and post again today , would love it if you could check back laters on my new updated code.

 

You have

//--- input parameters


followed by


int X;

which is a globally declared variable - no inputs. Then that is followed by a function.


int countOpenOrders()
{
   int Ticket=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if (!OrderSelect(i,SELECT_BY_POS))  continue;  //I don't fully understand this line, please help.
      //if (OrderSymbol() != _Symbol)       continue; //Is Symbol automatically the symbol of the chart      the EA is running in? Don't fully understand.
      //Also, if I only have one open position per chart/asset this above line is obsolete right?
      if (OrderMagicNumber() != magic)    continue;
      if (OrderType() == OP_BUY){X = OrderTicket();} //This way I get the orderTicket if there is an open order with the correct magic number, thus knowing which order to close later?
      }
      return (X);
}


that apparently is intended to count open orders, but returns a ticket number.

Then it seems that the function is not actually called.

You just check if OrdersTotal()==0 before placing an order so obviously if an order is placed by the same EA on another symbol or manually a new trade will not be placed by this EA.

 

First of, big thanks again for all the help guys. You are really patient and it's deeply appreciated. This community is great! :) Also my methodnames are kind of crappy.

 

Okey so now I've re-writtern the code and made it smaller and easier to read. All the methods are called. Hope this is it! :)

  

 

 (if imaTest-imaTest2 < 0) 

The function countOpenOrdersAndReturnOrderTicket (previously countOpenOrders), is supposed to go through all the open orders and return OrderTicket-number if there is an open order in the Symbol that the EA is running in. The method then changes the variable X from 0 to the OrderTicket making it > 0 and triggering the if later in the code to close the order. 

 

(if  imaTest-imaTest2 > 0)

The function countOpenOrdersToMaybeOpenANewOrder loops through all open orders to see that there is not already an open order in the symbol the EA is running in. If there isn't any open order it changes the variable Y from to 1 which we will later use in the code in an if-statement to see if we should go ahead and open a new order for this particular symbol. 

 

 

//--- input parameters

//Setting MagicNumer
int magic = 1;


int X = 0;
int countOpenOrdersAndReturnOrderTicket()
{
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if (!OrderSelect(i,SELECT_BY_POS))  continue;  //This line selects the position by iteration.
      if (OrderSymbol() != _Symbol)       continue; //_Symbol is the symbol of the chart it is running on.
      if (OrderMagicNumber() != magic)    continue;
      if (OrderType() == OP_BUY){X = OrderTicket();} //This way I get the orderTicket if there is an open order with the correct magic number, thus knowing which orderTicket to close later?
     }
      return (X);
}

int Y = 0;
int countOpenOrdersToMaybeOpenANewOrder()
{
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if (!OrderSelect(i,SELECT_BY_POS))  continue;
      if (OrderSymbol() != _Symbol)       continue;
      if (OrderType() != OP_BUY)          continue;
      int Y = 1;  //if we get to this line, I will set Y to 1 for later use in the code.
     }
        return(Y);
         //Should I do the sell logic here? Right now it's later in the code.  
}



//A bunch of different params for getting iMA-value
string symbol = NULL;
int timeFrame = 0;
int period = 2;
int period2 = 5;
int maShift = 0;
int lastBarShift = 0;
int antalOpenOrders;
double imaTest;
double imaTest2;

int order;
color Color = CLR_NONE;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
void init()
  {
    Alert("Function init startade");
  }
  
  
//+------------------------------------------------------------------+
//| start function                                                   |
//+------------------------------------------------------------------+
void start()
{
//Calculating value of two different MA's
imaTest = iMA(symbol,timeFrame,period, maShift,MODE_SMA,PRICE_MEDIAN,lastBarShift);

imaTest2 = iMA(symbol,timeFrame,period2, maShift,MODE_SMA,PRICE_MEDIAN,lastBarShift);

antalOpenOrders = OrdersTotal();



//OPENING ORDER
if((imaTest-imaTest2) > 0)
{
     countOpenOrdersToMaybeOpenANewOrder();
     if (Y > 0)
     {
       {OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Bid-200*Point, NULL,NULL, 1);
        Alert("Order opened for this particular asset");}
     }

}
//CLOSING ORDER
if (imaTest-imaTest2 < 0)
{
     countOpenOrdersAndReturnOrderTicket();  //returns X which is the ticket number of any open order of the particular symobl
      if (X > 0)
      {
      //Do I need to select the order before doing the OrderClose below?
      OrderClose (X, 0.01, Bid, 3);
      }
}

}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void deinit()
  {
      Alert("Function deinit startade");
  }

 I get 0 errors while compiling but 3 warnings, if the above code looks okey or at least good enough to work on with that will be the next step. 


Also a curios question, how long did it take for you guys for the ball to drop regarding knowledge of MetaEditor? 

/Johan 

 

Use descriptive names for your variables. X and Y may be OK for small amounts of code, but still not good practice in my opinion.

As you are using globally declared variables use something like


int BuyTicket;
int SellTicket;


then you can use a function like this


//+------------------------------------------------------------------+
void CheckOrders()
  {
   BuyTicket=0;       //Remember to reset global variables
   SellTicket=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS) && OrderSymbol()==_Symbol && OrderMagicNumber()==magic)
        {
         if(OrderType()==OP_BUY)
            BuyTicket=OrderTicket();
         if(OrderType()==OP_SELL)
            SellTicket=OrderTicket();
        }
     }
   return;
  }
//+------------------------------------------------------------------+


then you can use the variables BuyTicket and SellTicket in your conditions with no need to loop through the orders twice.
 
Keith Watford:



 

Thanks Keith, much dry:er code with only one loop.  

 

Now if nobody says otherwise, please do if the code still not look functionable :) 

 

Again, thanks for the help everybody.

 

 

Now I only have two warnings left, guess they don't matter? Or am I wrong.

Final code of the algo attached :) 

 

return value of 'OrderSend' should be checked
return value of 'OrderClose' should be checked  
 
JoBo: Now I only have two warnings left, guess they don't matter? Or am I wrong.
They're not wrong, you are. Check your return codes What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
 

Thanks for correcting me whroeder1, 

 

I just did the following to fix it, let me know if it's bananas.

 

globally declared  int oSend; and int oClose;

 

Then in the place where I open a new order I just added  oSend = .......  and did the same for the OrderClose()

if (buyTicket == 0)

      {

          oSend = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Bid-200*Point, NULL,NULL, magic);

          Alert("Order opened for this particular asset");

          Sleep(300000);

      } 

 
oSend = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Bid-200*Point, NULL,NULL, magic);

Alert("Order opened for this particular asset");
All you've done is suppressed the warning, you haven't checked anything.
Reason: