Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 248

 
STARIJ:

Internet's back on! Can I write to the post office?


Yes, I'm in touch. Text me.

 

Help to refine the EA I am a novice programmer, description:

The advisor works on two currency pairs EURUSD and USDCHF, it only opens two buy trades when there is a 10pp divergence (essentially a standard arbitrator).

Here is the condition: if ((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) || (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))

And it closes when total profit/loss reaches a certain value: if ((AccountProfit()>=10)||(AccountProfit()<=-20))


THE PROBLEM: It doesn't always open 2 trades, sometimes it opens 3. Or it opens two deals of the same currency. It needs: always opens 2 transactions on different currencies (one - on EURUSD; another - on USDCHF).



Here is the code itself:


extern double impulse = 10; // Global variables

extern double Lots = 1;


int start()

{

double ind2=iClose("EURUSD",PERIOD_M1,0);

double ind1=iOpen("EURUSD",PERIOD_M1,0);


double ind3=iClose("USDCHF",PERIOD_M1,0);

double ind4=iOpen("USDCHF",PERIOD_M1,0);


double oper1=ind2-ind1;

double EUR=(int)DoubleToStr(oper1*100000,0);


double oper2=ind3-ind4;

double CHF=(int)DoubleToStr(oper2*100000,0);


Comment(StringFormat("Output data\nEUR = %G\nCHF =%G",EUR,CHF));

if ((AccountProfit()>=10)||(AccountProfit()<=-20)) // Close Condition

Alert3();

if ((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) || (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point)) //open condition

if (OrdersTotal() == 0)

Alert1();

if (OrdersTotal() == 1)

Alert2();

return(0);

}


int Alert1()

{

if (OrdersTotal() == 0)

int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);

return(0);

}


int Alert2()

{

if(OrdersTotal() == 1)

int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);

return(0);

}


int Alert3()

{

while (OrdersTotal()>0)

if (OrderSelect(0, SELECT_BY_POS, MODE_TRADES)) //Close

int cl1=OrderClose (OrderTicket(),OrderLots(),Bid,3);

int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);

return(0);

}

 

Alexey Belyakov:  CУТЬ ПРОБЛЕММЫ: Не всегда открывает 2 сделки, а бывает открывает 3. Или открывает две сделки по одной валюте. Нужно чтобы: открывал всегда 2 сделки по разным валютам ( одна - по EURUSD; другая- по USDCHF)

The server is ordered to open the Euro. By the time it reaches the server, by the time the server ... So far, there are no orders. On the next tick the condition is fulfilled again and again the order to open the Euro. The server has opened the first order. Since there are 1 order, the command to open a second (and it is already the third!) order is sent.

I have made all functions void and removed return. Here is this part of the program (we pressed button SRC to insert it)

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0) Alert1();
     if(OrdersTotal() == 1) Alert2();
}

void Alert1()
{
  if (OrdersTotal() == 0)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);
}

void Alert2()
{
  if(OrdersTotal() == 1)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
}

and replaced it (a bit rough, but IMHO it is better than the original) with

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0)
  {
    int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0); 
    int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
    Sleep(60); // Дождаться следующего бара, а то еще пооткрывает
  }
}

There is an extra line in Alert3 function

  int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);
Instead of double CHF=(int)DoubleToStr(oper2*100000,0); try int CHF=oper2/_Point;
 
STARIJ:

replaced (crude, but IMHO better than the original) with

Not rude, but it will work with errors. If only because both orders go by Ask of the same character.
 
Alexey Kozitsyn:   Not rude, but it will work with errors. If only because both orders go by Ask of the same symbol.

Of course, you are absolutely right. Moreover, this error was in the source code, but it was disguised by using functions both from the author and you, as well as from me, a sinner. After I had removed the functions, the error had become obvious. I think that positions will be opened only by the symbol on whose chart the EA is located. Right?

 
STARIJ:

Of course, you are absolutely right. And this error was contained in the source code, but it was masked by the use of functions from the author, from you and from sinful me. After I had removed the functions, the error had become obvious. I think that positions will be opened only by the symbol on whose chart the EA is located. Right?

Yes, of course, if the conditions for the opening are fulfilled. The Ask for the second symbol should be obtained separately.
 
Hi all. The question is naive, it concerns the function OrdersTotal(). It's clear that it returns the number of orders, and the orders are numbered from 0 to N. But if the bars are numbered starting from the newly opened one in the history, i.e. the "fresh" bar is numbered 0 and the "old" one is numbered N. And in the function OrdersTotal(), I understand that everything happens the opposite - the oldest open order is numbered 0 and the "fresh" one is numbered as N. Did I get it right?
 
Youri Lazurenko:
Hi all. The question is naive, it concerns the function OrdersTotal(). It's clear that it returns the number of orders and the order numbering is from 0 to N. But if the bars are numbered starting from the newly opened one in the history, i.e. a "fresh" bar is numbered 0 and an old one - N. And in the function OrdersTotal(), I understand that everything happens the opposite - the oldest open order is numbered 0 and the "fresh" one is numbered as N. Did I get it right?

Quite, but there are nuances.

There was a time when sorting depended on sorting in the terminal. No user can say for sure if that time will come back "suddenly" when the sorting will depend on the terminal's sorting again. That's why it would be much safer to collect orders in an array and sort them by their open/close time - then you would know for sure that your sorting depends on time and not "suddenly" on sorting in the terminal.

 
Artyom Trishkin:

Quite, but there are nuances.

There was a time when sorting depended on sorting in the terminal. No user can say for sure if that time will come back "suddenly" when sorting will depend on the terminal's sorting again. That's why it's better to collect orders in array and sort them by open/close time - then you will know for sure that your sorting depends on time and not "suddenly" on sorting in the terminal.


Hello. Thank you for your reply. First I want to go back to your previous answer to my question, about the reverse cycle. Yesterday, before leaving for work, I wrote a reply, and today, I couldn't find my (and your) posts at all. As far as I understood, I asked it in a wrong branch. The reverse cycle is i--?

"That's why it's more reliable to collect orders in an array and sort them by open/close time" - this is very interesting, and I think it's more reliable and correct (and it seems to me, when you define the last order, it doesn't always get what you need). If it's not difficult, how do I do it (create an array by open time)?

And one more thing. I have not tried it yet. We have a profitable and losing (locking) order. The profit orders are closed using the trailing stop. I would like to have a note that orders have been closed so as to compare their total profit with that of losing orders and to close losing ones, if the balance is positive. I am interested exactly what orders have been closed.

 
STARIJ:

I assume positions will only open on the symbol on whose chart the EA is located. Right?

If your Expert Advisor is working on EURUSD, but you want to place BUY order on USDCHF

then in OrderSend you should use MarketInfo("USDCHF",MODE_ASK); instead of Ask (it will be for EURUSD)