Помогите разобраться с проблемой закрытия ордеров (ордера не закрываются). - страница 3

 
Игорь:
Вот журнал
 
Игорь:
 
Игорь:

138

ERR_REQUOTE

Новые цены


В тестере при закрытии позиции реквота может быть лишь в одном случае - неверно указана цена закрытия. Помните:

Buy открывается по Ask, а закрывается по Bid

Sell открывается по Bid, а закрывается по Ask

 
Artyom Trishkin:

138

ERR_REQUOTE

Новые цены


В тестере при закрытии позиции реквота может быть лишь в одном случае - неверно указана цена закрытия. Помните:

Buy открывается по Ask, а закрывается по Bid

Sell открывается по Bid, а закрывается по Ask

int start()
  {
   int ticket;

  //DeMarker
   double DM1,DM; 
   DM=iDeMarker(NULL,0,14,0);// 0 (1) бар
   DM1=iDeMarker(NULL,0,14,1);// 1 (2) бар

if(DM>0.3&&DM1<0.3&&CountBuy()<1) // открытие покупок
     {
      ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,0,0,0,NULL,Magic,0,CLR_NONE);
      
     }
 if(DM<0.7&&DM1>0.7&&CountBuy()>0) // закрытие покупок
 Print("Print(DM)=",DM,"Print(DM1)=",DM1, "Print(CountBuy())=",CountBuy() );
    {
     for(int i=OrdersTotal()-1; i>=0; i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
           {
            if(OrderMagicNumber()==Magic && OrderType()==OP_BUY)
               OrderClose(OrderTicket(),OrderLots(),Bid,3,clrNONE);
              Print( "OrderClose(OP_BUY) #", ticket);
              
           }
        }
        }
 
Игорь:

у меня так и есть

 
Игорь:

у меня так и есть

Не хватает функции обработки ошибок

Здесь гляньте

https://www.mql5.com/ru/forum/152182/page133#comment_3778225

 
Игорь:

у меня так и есть

В общем, вообще не глядя "на коленке" накидал для тестера открытие/закрытие Buy-позиций. Недочётов там - тьма-тьмущая, но то не важно - важен принцип. Главное, что работает открытие/закрытие.

//+------------------------------------------------------------------+
//|                                                 TestDeMarker.mq4 |
//|              Copyright 2018, Artem A. Trishkin, Skype artmedia70 |
//|                         https://www.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Artem A. Trishkin, Skype artmedia70"
#property link      "https://www.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
//--- Внешние переменные
input int      InpMagicNumber =  100500;  // MagicNumber
input uint     InpSlippage    =  3;       // Slippage
input uint     InpPeriodDeM   =  14;      // DeMarker period
input double   InpDemLevelUP  =  0.7;     // DeMarker upper level
input double   InpDemLevelDN  =  0.3;     // DeMarker lower level
//--- Глобальные переменные
int      slippage;
int      period_dem;
double   level_up;
double   level_dn;
struct SPosData
  {
   uint  number_buy;
   uint  number_sell;
  } PosData;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   slippage=(int)InpSlippage;
   period_dem=int(InpPeriodDeM<1 ? 1 : InpPeriodDeM);
   level_dn=(InpDemLevelDN<0 ? 0 : InpDemLevelDN>0.9 ? 0.9 : InpDemLevelDN);
   level_up=(InpDemLevelUP>1 ? 1 : InpDemLevelUP<=level_dn ? level_dn+0.1 : InpDemLevelUP);
//---
   CountClear();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   FillingPositionsData(InpMagicNumber);
//--- Open Buy
   if(CountBuy()==0)
     {
      if(DeM0()>level_dn && DeM1()<=level_dn)
        {
         double price=SymbolInfoDouble(NULL,SYMBOL_ASK);
         ResetLastError();
         bool res=OrderSend(NULL,ORDER_TYPE_BUY,0.1,price,slippage,0,0,NULL,InpMagicNumber,0,clrBlue);
         if(!res)
           {
            Print("Ошибка открытия позиции Buy ",GetLastError());
           }
        }
     }
//--- Close Buy
   else
     {
      if(DeM0()<level_up && DeM1()>=level_up)
        {
         bool res=ClosePositions(ORDER_TYPE_BUY,InpMagicNumber);
        }
     }
   
//---
  }
//+------------------------------------------------------------------+
//| Закрывает позиции (только для тестера)                           |
//+------------------------------------------------------------------+
bool ClosePositions(const ENUM_ORDER_TYPE order_type,const int magic_number)
  {
   if(order_type>ORDER_TYPE_SELL)
     {
      Print(__FUNCTION__,": Ошибка! Неверно задан тип ордера: ",EnumToString(order_type));
      return false;
     }
   double price=(order_type==ORDER_TYPE_BUY ? SymbolInfoDouble(NULL,SYMBOL_BID) : SymbolInfoDouble(NULL,SYMBOL_ASK));
   color  clr_close=(order_type==ORDER_TYPE_BUY ? clrDodgerBlue : clrOrangeRed);
   bool   res=false;
   int total=OrdersTotal()-1;
   for(int i=total; i>WRONG_VALUE; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS))
        {
         if(OrderMagicNumber()!=magic_number)   continue;
         ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderType();
         if(type==order_type)
           {
            ResetLastError();
            res=OrderClose(OrderTicket(),OrderLots(),price,slippage,clr_close);
            if(!res)
              {
               Print("Ошибка закрытия позиции ",(order_type==ORDER_TYPE_BUY ? "Buy" : "Sell"),": ",GetLastError());
              }
           }
        }
     }
   return res;
  }
//+------------------------------------------------------------------+
//| Заполняет данные по количеству позиций                           |
//+------------------------------------------------------------------+
uint FillingPositionsData(const int magic_number)
  {
   CountClear();
   int total=OrdersTotal()-1;
   for(int i=total; i>WRONG_VALUE; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS))
        {
         if(OrderMagicNumber()!=magic_number)   continue;
         ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderType();
         if(type>ORDER_TYPE_SELL)               continue;
         if(type==ORDER_TYPE_BUY)
            PosData.number_buy++;
         if(type==ORDER_TYPE_SELL)
            PosData.number_sell++;
        }
     }
    return CountAll();
  }
//+------------------------------------------------------------------+
//| Возвращает количество Buy                                        |
//+------------------------------------------------------------------+
uint CountBuy(void)
  {
   return PosData.number_buy;
  }
//+------------------------------------------------------------------+
//| Возвращает количество Sell                                       |
//+------------------------------------------------------------------+
uint CountSell(void)
  {
   return PosData.number_sell;
  }
//+------------------------------------------------------------------+
//| Возвращает общее количество количество позиций                   |
//+------------------------------------------------------------------+
uint CountAll(void)
  {
   return PosData.number_buy+PosData.number_sell;
  }
//+------------------------------------------------------------------+
//| Очищает данные о количестве позиций                              |
//+------------------------------------------------------------------+
void CountClear(void)
  {
   PosData.number_buy=PosData.number_sell=0;
  }
//+------------------------------------------------------------------+
//| Возвращает данные по DeMarker                                    |
//+------------------------------------------------------------------+
double GetDeMarker(int shift)
  {
   return iDeMarker(NULL,PERIOD_CURRENT,period_dem,shift);
  }
//+------------------------------------------------------------------+
//| DeMarker(0)                                                      |
//+------------------------------------------------------------------+
double DeM0(void)
  {
   return GetDeMarker(0);
  }
//+------------------------------------------------------------------+
//| DeMarker(1)                                                      |
//+------------------------------------------------------------------+
double DeM1(void)
  {
   return GetDeMarker(1);
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

В общем, вообще не глядя "на коленке" накидал для тестера открытие/закрытие Buy-позиций. Недочётов там - тьма-тьмущая, но то не важно - важен принцип. Главное, что работает открытие/закрытие.

Спасибо за помощь. Теперь точно переучиваться придётся, чтобы разобраться. В нашем деле самое главное результат.

 
Renat Akhtyamov:

Не хватает функции обработки ошибок

Здесь гляньте

https://www.mql5.com/ru/forum/152182/page133#comment_3778225

Спасибо Ренат
 
Как не прискорбно осознать, всё программирование на MQL4 перешло на модули (функции). Я против функций конечно не возражаю. Они конечно нужны в определённых ситуациях, правда когда они "сидят друг на друге" в простейших построениях это больше вносит хаус в понимании программного кода и особенно "раздувание" последнего. Скорее всего это диктуют разработчики данного ПО. А в целом большое спасибо тем кто принимал участие в решении данной проблемы (закрытие позиций при определённом условии). Но к сожалению при условии, что все перешли на безусловный переход  (функции), вышеуказанная проблема не решина.
Причина обращения: