Learning and writing together in MQL5 - page 25

 
Khomtchenko:

Where I made a mistake. Why do I get an enlarged position.

There is a concept called netting. According to the philosophy of NETTING, all unidirectional trades increase the position, while multidirectional trades close, decrease or reverse it.

Khomtchenko:
Checking by indicator - if there should be a Buy position, but there is a Sell, then do Buy.

If we draw a conclusion from the line, we understand that with an existing Sell a new Buy position will close or cut the existing position.

PS

By the way, TP and SL in MT5 are set according to the last trade, so they should be monitored too...

 
molotkovsm:

What is the correct way to delete all orders with a certain mode?

I have two functions for this, check_orders checks for orders with a certain mode, and remove_sl deletes them:

The problem is that in my EA's journal, I get lines like this:

2011.05.11 21:40:19 Trades '726238' : failed cancel order #4375237 buy 0.00 at 0.00000 [Invalid request]
I.e. unnecessary requests are sent to the trade server with a request to delete the order that has already been requested.

I need to go through the list of orders from top to bottom, e.g:

      while(check_orders()==true)
        {
         int orders=OrdersTotal();
         for(counter01=orders-1; counter01>=0; counter01--)
           {
            counter02=OrderGetTicket(counter01);
            if(OrderGetInteger(ORDER_MAGIC)!=magick)
               continue;
            remove_request.action=TRADE_ACTION_REMOVE; remove_request.order=counter02;
            if(OrderCheck(start_request,check_result)==true)
               OrderSend(start_request,trade_result);
           }
        }
 

ЗЫ Если вы знаете инструмент то для поиска позиции совсем не нужно перебирать все позиции, достаточно воспользоваться вот этой функцией:

bool  PositionSelect(
   string  symbol     // имя инструмента
   );

Thank you. I'll give it a try.

By the way, I use one symbol.

According to the philosophy of this very NETTING, all unidirectional trades increase the position and multidirectional trades close, decrease or reverse.

Exactly!

We conclude from the line we understand that with an existing Sell a new Buy will close or trim an existing position.

PS

By the way, TP and SL in MT5 are set according to the last trade, so they should be monitored too...

From your words, Mr.Interesting , I understand that I understand everything correctly.

I am using the same lots. I am using the same stops. Everything is as it should be. But something is wrong!

Okay. Promised to do two EAs and show the difference. I'll do it. I don't want to put the best one out there for everyone to see.

 

So, who among the respected experts can I email two EAs for the same strategy on mql4 and on mql5?

I just need to figure out what I'm doing wrong, that's all. Well, different price statistics can not change the test results by 2-3 times. It's about programming.

Lizar,Renat,sergeev, HELP me. I can give you all the experts to review the code. The Expert Advisor is simple but effective. I can still improve it, but I have simplified it to the maximum, to make the essence of the problem clearer.

I also apologize to everyone for being intemperate in their statements. I'm embarrassed. But I VERY much want to understand everything!

 
You can post it here, so that those who are interested can take a look.
 
Rosh:

Need to go through the list of orders from top to bottom, e.g. like this:

Doesn't help, apparently the order is deleted successfully and then another request is sent:

2011.05.12 16:42:57 Trades '726238' : cancel order #4388299 buy stop 0.02 EURUSD at 1.41700 done
2011.05.12 16:42:57 Trades '726238' : cancel order #4388299 buy stop 0.02 EURUSD at 1.41700
2011.05.12 16:42:58 Trades '726238' : failed cancel order #4388299 buy 0.00 at 0.00000 [Invalid request] - already a buy while buy stop was

 
//+------------------------------------------------------------------+
//|                                                     M2H1mql5.mq5 |
//|                              Copyright 2011, Yuriy V.Khomtchenko |
//|                                         mr.Khomtchenko@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, Yuriy V.Khomtchenko"
#property link      "mr.Khomtchenko@gmail.com"
#property version   "1.00"

MqlRates price[2];

double m_buff_EMAs[];
double m_buff_EMAb[];
double Ask; 
double Bid; 
int N=2;
double m_handle_ema1, m_handle_ema3;
extern double Lots = 0.1;
extern int Period_MA1=4;   
extern int Period_MA3=21;
bool mm =0;
bool New_Bar=false;
int const magic=102406;
double Mas0, Mab0, Mas1, Mab1;

double  
         StopLoss=200,                  
         TakeProfit=3200;                  
   
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
  m_handle_ema1=iMA(_Symbol,_Period,Period_MA1,0,MODE_EMA,PRICE_CLOSE);
  m_handle_ema3=iMA(_Symbol,_Period,Period_MA3,0,MODE_EMA,PRICE_CLOSE);
 
//---
   return(0);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   GetIns();
   if (!PositionSelect(_Symbol))
    { 
     if(Mas0>Mab0 && Mas1<Mab1)  OpenBuy(Lots,10,"EUR/USD (Buy)",102406);
     if(Mas0<Mab0 && Mas1>Mab1)  OpenSell(Lots,10,"EUR/USD (Sell)",102406);
    }
  if (PositionSelect(_Symbol)) TryToClose();
  }
//+------------------------------------------------------------------+
void GetIns()
{
 CopyRates(_Symbol, _Period,0,2,price); 
 CopyBuffer(m_handle_ema1,0,0,N,m_buff_EMAs);
 ArraySetAsSeries(m_buff_EMAs,true);
 CopyBuffer(m_handle_ema3,0,0,N,m_buff_EMAb);
 ArraySetAsSeries(m_buff_EMAb,true);
 Mas0=m_buff_EMAs[0];
 Mas1=m_buff_EMAs[1];
 Mab0=m_buff_EMAb[0];
 Mab1=m_buff_EMAb[1];
 MqlTick last_tick;//Здесь будут храниться цены последнего пришедшего тика
 SymbolInfoTick(_Symbol,last_tick);//заполняем структуру last_tick последними ценами текущего символа.
 Ask=last_tick.ask;//Обновляем переменные Ask и Bid для дальнейшего использования
 Bid=last_tick.bid;
 return;
}

//Функция открытия длинной (Long) позиции. Указываем также значения переменных по умолчанию
int OpenBuy(double volume,int slippage=10,string comment="EUR/USD (Buy)",int magic0=102406)
  {
   MqlTradeRequest my_trade;//объявляем структуру типа MqlTradeRequest для формирования запроса
   MqlTradeResult my_trade_result;//в этой структуре будет ответ сервера на запрос.

   //далее заполняеем все НЕОБХОДИМЫЕ поля структуры запроса.
   my_trade.action=TRADE_ACTION_DEAL;//Установить торговый ордер на немедленное совершение сделки с указанными 
                                     //параметрами (поставить рыночный ордер)
   my_trade.symbol=Symbol();//указываем в качестве валютной пары - текущую валютную пару 
                            //(ту, на которой запущен советник)
   my_trade.volume=NormalizeDouble(volume,1);//размер лота
   my_trade.price=NormalizeDouble(Ask,_Digits);//Цена, при достижении которой ордер должен быть исполнен. 
   //В нашем случае для TRADE_ACTION_DEAL это текущая цена и ее, согласно инструкции указывать не обязательно.
   my_trade.sl=NormalizeDouble(Ask-StopLoss*_Point,_Digits);//стоплосс ордера (цена при которой следует закрыть 
                                                            //убыточную сделку)
   my_trade.tp=NormalizeDouble(Ask+TakeProfit*_Point,_Digits);//тейкпрофит (цена при которой следует закрыть
                                                              // прибыльную сделку)
   my_trade.deviation=slippage;//проскальзывание в пунктах (при тестировании особой роли не играет, т.к. 
                               //проскальзывания не бывает на тестах)
   my_trade.type=ORDER_TYPE_BUY;//тип рыночного ордера (покупаем)
   my_trade.type_filling=ORDER_FILLING_AON;//Указываем как исполнять ордер. (All Or Nothing - все или ничего) 
   //Сделка может быть совершена исключительно в указанном объеме и по цене равной или лучше указанной в ордере.
   my_trade.comment=comment;//комментарий ордера
   my_trade.magic=magic;//магическое число ордера

   ResetLastError();//обнуляем код последней ошибки 
   if(OrderSend(my_trade,my_trade_result))//отправляем запрос на открытие позиции. При этом проверяем 
                                          //успешно ли прошла отправка запроса
     {
      // Если сервер принял ордер то смортрим на результат 
  
      Print("Код результата операции - ",my_trade_result.retcode);
     }
   else
     {
      //Сервер не принял ордер в нем есть ошибки, выводим их в журнал
      Print("Код результата операции - ",my_trade_result.retcode);
      Print("Ошибка открытия ордера = ",GetLastError());
     }
return(0);// Выходим из функции открытия ордера     
}

//функция открытия короткой (Short) позиции. Аналогична функции открытия длинной позиции.
int OpenSell(double volume,int slippage=10,string comment="Open Short EUR/USD (Sell)",int magic0=102406)
  {
   MqlTradeRequest my_trade;
   MqlTradeResult my_trade_result;
   my_trade.action=TRADE_ACTION_DEAL;
   my_trade.symbol=Symbol();
   my_trade.volume=NormalizeDouble(volume,1);
   my_trade.price=NormalizeDouble(Bid,_Digits);
   my_trade.sl=NormalizeDouble(Bid+StopLoss*_Point,_Digits);
   my_trade.tp=NormalizeDouble(Bid-TakeProfit*_Point,_Digits);
   my_trade.deviation=slippage;
   my_trade.type=ORDER_TYPE_SELL;
   my_trade.type_filling=ORDER_FILLING_AON;
   my_trade.comment=comment;
   my_trade.magic=magic;

   ResetLastError();
   if(OrderSend(my_trade,my_trade_result))
     {

      Print("Код результата операции - ",my_trade_result.retcode);
     }
   else
     {
      Print("Код результата операции - ",my_trade_result.retcode);
      Print("Ошибка открытия ордера = ",GetLastError());
      }
return(0);
}

int TryToClose()
{
       if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
       if(Mas0<Mab0 && Mas1>Mab1) OpenSell(Lots,10,"EUR/USD (Sell)",102406);
      if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
       if(Mas0>Mab0 && Mas1<Mab1) OpenBuy(Lots,10,"EUR/USD (Buy)",102406);
  return(0);
}

similar, but on mql4:

//+------------------------------------------------------------------+
//|                                                       H1EU2M.mq4 |
//|                             Copyright © 2011 Khomtchenko V. Yury |
//|                                         mr.Khomtchenko@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011 Khomtchenko V. Yury"
#property link      "mr.Khomtchenko@gmail.com"

 extern double Lots = 0.1;

 extern int Period_MA1=4;    
 extern int Period_MA3=21;
  bool mm =0;
 bool New_Bar=false;
  int magic=10605;
 double Mas0, Mal0, Mab0, Mas1, Mal1, Mab1;
 int mt,ticket, total, mtotal, i, count, time_oc, md, refresh;
 double  
         SL=0.002,                 
         kmin=1,                   
         border=500,
         TP=0.032;                  
            
int      delay=3200,//3200
         maxr=10;
int      handle;

int init()
  {
//----
 time_oc=0; 
 md=0; 
 refresh=0;
//----
   return(0);
  }

int start()
  {
//----
  GetIns();
 

  OpenBuy();
  OpenSell(); 
  
 
  CloseSellEnd();
  CloseBuyEnd();
//----
   return(0);
  }
//+------------------------------------------------------------------+

int GetIns()
{
 Mas0=iMA(NULL,0,Period_MA1,0,MODE_EMA,PRICE_CLOSE,0);//40
 Mab0=iMA(NULL,0,Period_MA3,0,MODE_EMA,PRICE_CLOSE,0);//40
 Mas1=iMA(NULL,0,Period_MA1,0,MODE_EMA,PRICE_CLOSE,1);//40
 Mab1=iMA(NULL,0,Period_MA3,0,MODE_EMA,PRICE_CLOSE,1);//40
}

int OpenBuy()
{
total=Total();
  
   if(Total()<1) 
     {//2
      if(Mas0>Mab0 && Mas1<Mab1 )
        {//21
        refresh=0;
        while(true){ RefreshRates();
        Print("Try to open BUY H1:",Ask,"(",refresh,")", ", TotalOrders:",OrdersTotal(),", My orders:", Total());
        refresh++;
        ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,50,Ask-SL,Ask+TP,"BUY 60",magic,0,Green);
        if (refresh>=maxr) return(0); 
         if(ticket>0)
           {//22
            Print("BUY order opened H1: ",Ask, ", TotalOrders:",OrdersTotal(),", My orders:", Total());
            time_oc=TimeLocal( );
            md=0;
            return(0);
           }//22
           continue;  }
        }//21
      }//2
}

int OpenSell()
{
 total=Total();
       if(Total()<1) 
       {
        if(Mas0<Mab0 && Mas1>Mab1)
          {
          refresh=0;
          while(true){ RefreshRates();
           Print("Try to open Sell H1: ",Bid,"(",refresh,")", ", TotalOrders:",OrdersTotal(),", My orders:", Total());
           refresh++;
           ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,50,Bid+SL,Bid-TP,"SELL 60",magic,0,Red);
           if (refresh>=maxr) return(0); 
           if(ticket>0)
             {
              Print("SELL order opened H1: ",Bid, ", TotalOrders:",OrdersTotal(),", My orders:", Total());
              time_oc=TimeLocal( );
              md=0;
              return(0);
             } 
           continue;  }
          }
        }
}

int CloseBuyEnd()
{
if (Total()>0)
     {//3
     mtotal=OrdersTotal();
     for (i=0; i<mtotal; i++)
      {//for
      if(OrderSelect(i,SELECT_BY_POS)==true)
       {//31
       if (OrderType()==OP_BUY && OrderMagicNumber()==magic)// check for long position (BUY) close possibility
        {//32
         if(Mas0<Mab0 && Mas1>Mab1)//70
          {//33
          refresh=0;
          while(true){ RefreshRates();
          refresh++;
          ticket=OrderClose(OrderTicket(),OrderLots(),Bid,50,Red);
          if (refresh>=maxr) return(0);
          if (ticket>0)
           {//331
            Print("BUY order CLOSED (TP): ",OrderClosePrice());
            time_oc=0;
            md=0;
            return(0);
           }//331
           continue;  }
           }//33
         }//32 
        }//31
        }//for
     }//3
}

int CloseSellEnd()
{
mtotal=OrdersTotal();
if (Total()>0)
     {//3
     for (i=0; i<mtotal; i++)
      {//for
      if(OrderSelect(i,SELECT_BY_POS)==true)
       {//31
       if (OrderType()==OP_SELL && OrderMagicNumber()==magic)// check for long position (SELL) close possibility
         {//32
          if(Mas0>Mab0 && Mas1<Mab1)//70
          {//33
          refresh=0;
          while(true){ RefreshRates();
          refresh++;
           ticket=OrderClose(OrderTicket(),OrderLots(),Ask,50,Green);
           if (refresh>=maxr) return(0);
            if (ticket>0)
             {//351
              Print("SELL order closed (TP): ",OrderClosePrice()); 
              time_oc=0;
              md=0;
              return(0);
             }//351
             continue;  }
          }//33
         }//32 
        }//31
        }//for
     }//3  
}

int Total()
{
 count=0;
 for (i=0;i<OrdersTotal();i++)
  {
   OrderSelect(i,SELECT_BY_POS);
   if (OrderMagicNumber( )==magic) {count++;}
  }
 return(count);
}

Well, look and compare. I messed up somewhere... The difference is substantial.

 
molotkovsm:

Doesn't help, apparently the order is deleted successfully and then another request is sent:

2011.05.12 16:42:57 Trades '726238' : cancel order #4388299 buy stop 0.02 EURUSD at 1.41700 done
2011.05.12 16:42:57 Trades '726238' : cancel order #4388299 buy stop 0.02 EURUSD at 1.41700
2011.05.12 16:42:58 Trades '726238' : failed cancel order #4388299 buy 0.00 at 0.00000 [Invalid request] - already a buy while buy stop was

I'm ashamed to admit that I still have not mastered the art of telepathy.
 
I almost forgot. EAs work on Eur/Usd H1. Tested from 1.01.2010 to 1.05.2011.
 
Rosh:
I am ashamed to admit that I still have not mastered the art of telepathy.

I will repeat the question:

How do I correctly delete all orders with a certain mag?

I have two functions for this, check_orders checks for orders with a certain mode and remove_sl removes them:

void remove_sl()
     {
      int counter01;
      ulong counter02;
      while(check_orders()==true)
        {
         for(counter01=0; counter01<OrdersTotal(); counter01++)
           {
            counter02=OrderGetTicket(counter01);
            if(OrderGetInteger(ORDER_MAGIC)!=magick)
               continue;
            remove_request.action=TRADE_ACTION_REMOVE; remove_request.order=counter02;
            if(OrderCheck(start_request,check_result)==true)
               OrderSend(start_request,trade_result);
           }
        }
     }



bool check_orders()
     {
      int counter01;
      bool order_exist=false;
      for(counter01=0; counter01<OrdersTotal(); counter01++)
        {
         OrderGetTicket(counter01);
         if(OrderGetInteger(ORDER_MAGIC)==magick)
           {
            order_exist=true;
            break;
           }
        }
      return(order_exist);
     }

The problem is that in EA's journal these lines appear:

2011.05.11 21:40:19 Trades '726238' : failed cancel order #4375237 buy 0.00 at 0.00000 [Invalid request]
I.e. unnecessary requests are sent to the trade server to remove the order the request to remove which had already been sent.

You have advised the following:

You need to go through the list of orders from top to bottom, for example like this:

 while(check_orders()==true)
        {
         int orders=OrdersTotal();
         for(counter01=orders-1; counter01>=0; counter01--)
           {
            counter02=OrderGetTicket(counter01);
            if(OrderGetInteger(ORDER_MAGIC)!=magick)
               continue;
            remove_request.action=TRADE_ACTION_REMOVE; remove_request.order=counter02;
            if(OrderCheck(start_request,check_result)==true)
               OrderSend(start_request,trade_result);
           }
        }

I tried to do as you said, but the problem remains - the pending order is deleted first, then another request is sent to delete the same order. Here is an example of the log lines:

2011.05.12 16:42:57 Trades '726238' : cancel order #4388299 buy stop 0.02 EURUSD at 1.41700 done - successfully deleted the order
2011.05.12 16:42:57 Trades '726238' : cancel order #4388299 buy stop 0.02 EURUSD at 1.41700 - Another request is being sent
2011.05.12 16:42:58 Trades '726238' : failed cancel order #4388299 buy 0.00 at 0.00000 [Invalid request] - it was buy for some reason.

This does not happen every time, but sometimes, and it does not affect the Expert Advisor's operation. I just want to do everything correctly, not to load the trade server with empty requests, and to sort out the problem.

Thank you for your replies and your willingness to help.


Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров - Документация по MQL5
Reason: