Изучаем и пишем вместе на MQL5 - страница 25

 
Khomtchenko:
 

Где я ошибся. Почему я получаю укрупненные позиции.

Есть такое понятие - неттинг называется. Согдасно философии этого самого НЕТТИНГА все однонаправленные сделки увеличивают позицию, а разнонаправленные закрывают, уменьшают или переворачивают.

Khomtchenko:
Проверка по индикатором такая - если должна быть позиция Бай, а существует Селл, то делаем Бай.

Делаем вывод из строчки понимаем что при существующем Sell новый Buy закроет или урежет существующую позицию.

PS

Кстати, TP и SL в MT5 выставляются по последней сделке, так что их тоже стоит контролировать...

 
molotkovsm:

Как правильно удалить все ордера с определенным мэджиком?

У меня для этого исп. две функции, check_orders проверяет наличие ордеров с опр. меджиком, а remove_sl удаляет:

Проблема в том, что в журнале эксперта появляются вот такие строки:

2011.05.11 21:40:19 Trades '726238' : failed cancel order #4375237 buy 0.00 at 0.00000 [Invalid request]
т.е. идут лишние обращения на торговый сервер с запросом удаления ордера, запрос на удаление которого уже отправлялся. 

Необходимо перебирать список ордеров сверху вниз, например так:

      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     // имя инструмента
   );

Спасибо. Попробую. 

 Кстати я использую один символ. 

Согдасно философии этого самого НЕТТИНГА все однонаправленные сделки увеличивают позицию, а разнонаправленные закрывают, уменьшают или переворачивают. 

Так точно!

Делаем вывод из строчки понимаем что при существующем Sell новый Buy закроет или урежет существующую позицию.

PS

Кстати, TP и SL в MT5 выставляются по последней сделке, так что их тоже стоит контролировать...

 Из Ваших слов, г-н Interesting, я понимаю, что все понимаю правильно. 

 

Я использую один и тот же лот. Я использую одни и те же стопы. Все как надо. Но что-то не так!

 

Ладно. Обещал сделать два советника и показать разницу. Буду делать. Не хочу самого хорошего всем на показ выставлять. 

 

Ну вот кому из уважаемых экспертов можно в личку закинуть два советника по одной и той же стратегии на mql4 и на mql5?

Мне просто надо разобраться, что я не так делаю и все. Ну разная статистика цен не может изменить результаты тестирования в 2-3 раза. Тут дело в программировании. 

LizarRenatsergeev , ПОМОГИТЕ. Могу вам всем дать экспертов на заценку кода. Советник прост, но результативен. Можно еще улучшить его, но я упростил советника максимально, чтобы суть проблемы была яснее.

И прошу прощения у всех за несдержанность в высказываниях. Мне стыдно. Но я ОЧЕНЬ ХОЧУ разобраться во всем!  

 
вы тут выложите, кто заинтересуется посмотрят.
 
Rosh:

Необходимо перебирать список ордеров сверху вниз, например так:

Не помогает, видимо, ордер удаляется успешно, а потом отправляется еще один запрос:

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]  - уже почему то buy, а был buy stop

 

 
//+------------------------------------------------------------------+
//|                                                     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);
}

аналогично, но на 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);
}

 Ну вот смотрите и сравнивайте. Где-то я накосячил... Разница существенная.

 
molotkovsm:

Не помогает, видимо, ордер удаляется успешно, а потом отправляется еще один запрос:

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]  - уже почему то buy, а был buy stop

Стыдно признаться, но все еще не овладел искусством телепатии.
 
Чуть не забыл. Советники работают на Eur/Usd H1. Тестировал с 1.01.2010 по 1.05.2011.
 
Rosh:
Стыдно признаться, но все еще не овладел искусством телепатии.

Я повторю вопрос:

Как правильно удалить все ордера с определенным мэджиком?

У меня для этого исп. две функции, check_orders проверяет наличие ордеров с опр. меджиком, а remove_sl удаляет:

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);
     }

Проблема в том, что в журнале эксперта появляются вот такие строки:

2011.05.11 21:40:19 Trades '726238' : failed cancel order #4375237 buy 0.00 at 0.00000 [Invalid request]
т.е. идут лишние обращения на торговый сервер с запросом удаления ордера, запрос на удаление которого уже отправлялся.

 

Вы посоветовали следующее:

Необходимо перебирать список ордеров сверху вниз, например так:

 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);
           }
        }

Я попробовал сделать, как вы сказали, но проблема осталась - отложенный ордер сначала удаляется, потом отправляется еще один запрос на удаление того же ордера. Вот пример строк из журнала:

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]                  - уже почему то buy, а был buy stop

Это происходит не каждый раз, а иногда, и на работу эксперта не влияет. Просто хочется сделать все правильно,  не загружать пустыми запросами торговый сервер, и разобраться в проблеме.

 

Спасибо за ответы, и ваше желание помочь.


 

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