Советник не всегда открывает ордера, и не всегда их модифицирует. OrderSend error 134 и OrderModify error 4108.

 

Здравствуйте. Не могу понять, в каком месте я допустил ошибку. Условия, связанные с индикаторами, написаны правильно, и все функции тоже. Проблема описана в шапке, стоит добавить что и манименеджмент работает неправильно.

За помощь буду искринне благодарен. 

Собственно, код самого эксперта:

#property copyright "Copyright 2014, Mark"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern string main = "Main:";
extern int multiplerTP = 2;
extern int PercentRisk = 2;
extern int BULevel = 0;
extern double FixLot = 0;
extern int SizeBar = 10;
extern int Otstup = 3;
extern int MaxRast = 10;

extern string tma = "TrMA:";
extern string TimeFrames = "current time frame";
input int HalfLength = 20;
input int Price = 6;
input double BandsDeviations = 3;


extern string bsa = "Buy sell:";
input int Risk = 5;
input int CandleTF = 240;

extern string bsw1 = "Buy Sellsw1:";
input int Risk1 = 13;
input int Candle1 = 60;

extern string bsw2 = "Buy Sellsw2:";
input int Risk2 = 7;
input int Candle2 = 240;






#include <stdlib.mqh>   

bool   gbDisabled    = False;          // Флаг блокировки советника
color  clOpenBuy     = LightBlue;      // Цвет значка открытия покупки
color  clOpenSell    = LightCoral;     // Цвет значка открытия продажи
color  clModifyBuy   = Aqua;           // Цвет значка модификации покупки
color  clModifySell  = Tomato;         // Цвет значка модификации продажи
int    Slippage      = 3;              // Проскальзывание цены
int    NumberOfTry   = 5;              // Количество торговых попыток
bool   UseSound      = True;           // Использовать звуковой сигнал
string NameFileSound = "expert.wav";   // Наименование звукового файла 

double Rb, Rs, Stop;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if (Digits == 3 || Digits == 5)
   {
   SizeBar*=10;
   Otstup*=10;
   MaxRast*=10;  
   Rb*=10;
   Rs*=10; 
   Stop*=10;
   } 
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  double SL, TP;

      //  Проверяем, нет ли активных ордеров по паре на которой работает советник. 
  int b=0,s=0;
  for(int f=OrdersTotal()-1; f>=0; f--)
    if(OrderSelect(f,SELECT_BY_POS)==true)
      if(OrderSymbol()==Symbol())
           {
            if(OrderType()==0)b++; 
            if(OrderType()==1)s++; 
           }
           
           
          
  
      // Получаем данные с индикаторов.
  double TMA1, TMA2, BS1, BS2, BSW1_1, BSW1_2, BSW2_1, BSW2_2;;

  
  TMA1 = iCustom(Symbol(), 0, "TriangularMA centered abands alerts 2", TimeFrames, HalfLength, Price, BandsDeviations, 1, 1);
  TMA2 = iCustom(Symbol(), 0, "TriangularMA centered abands alerts 2", TimeFrames, HalfLength, Price, BandsDeviations, 2, 1);
  
  BS1 = iCustom(Symbol(), 0, "Buy-Sell_Alerts", Risk, CandleTF, 0, 1);
  BS2 = iCustom(Symbol(), 0, "Buy-Sell_Alerts", Risk, CandleTF, 1, 1);
  
  BSW1_1 = iCustom(Symbol(), 0, "Buy-Sell_Alerts", Risk1, Candle1, 0, 1);
  BSW1_2 = iCustom(Symbol(), 0, "Buy-Sell_Alerts", Risk1, Candle1, 1, 1);
  
  BSW2_1 = iCustom(Symbol(), 0, "Buy-Sell_Alerts", Risk2, Candle2, 0, 1);
  BSW2_2 = iCustom(Symbol(), 0, "Buy-Sell_Alerts", Risk2, Candle2, 1, 1);  
  
  // Рассчитываем расстояние между индикаторами.
  if (TMA1>BS1){Rb = ((TMA1 - BS1)/Point)*Point;}
  if (TMA1<BS1){Rb = ((BS1 - TMA1)/Point)*Point;}
  if (TMA2<BS2){Rs = ((BS2 - TMA2)/Point)*Point;}
  if (TMA2>BS2){Rs = ((TMA2 - BS2)/Point)*Point;}
  
  
       double Lot;
          if (Rb<=MaxRast)
       {
       SL = NormalizeDouble(BS1-(Otstup*Point), Digits);
       Stop = ((Ask - SL)/Point)*Point;
       }
       
          if (Rb>MaxRast)
       {
       SL = NormalizeDouble(TMA1-(Otstup*Point), Digits);
       Stop = ((Ask - SL)/Point)*Point;       
       }
       
          if (Rs<=MaxRast)
       {
       SL = NormalizeDouble(BS2+(Otstup*Point), Digits);
       Stop = ((SL - Bid)/Point)*Point;
       }
       
          if (Rs>MaxRast)
       {
       SL = NormalizeDouble(TMA2+(Otstup*Point), Digits);
       Stop = ((SL - Bid)/Point)*Point;
       }
       
   if (FixLot>0)
   {
   Lot = FixLot;
   }
   else if (FixLot==0)
   {
   Lot = LotsByRisk(PercentRisk, Stop);
   }

  
      // Проверяем условия и выполняем работу с ордерами.
  if (b==0 && s==0)
  {
    if (BS1>0 && BSW1_1>0 && BSW2_1>0)
    {  
       if (Rb<=MaxRast)
       {int ticket = OpenPosition(Symbol(), OP_BUY, Lot);

       SL = NormalizeDouble(BS1-(Otstup*Point), Digits);
       TP = NormalizeDouble(Ask + (((Ask - SL)/Point)*Point)*multiplerTP, Digits);
       ModifyOrder(0, SL, TP);
       }
       
       
       if (Rb>MaxRast)
       {int ticket = OpenPosition(Symbol(), OP_BUY, Lot);

       SL = NormalizeDouble(TMA1-(Otstup*Point), Digits);
       TP = NormalizeDouble(Ask + (((Ask - SL)/Point)*Point)*multiplerTP, Digits);
       ModifyOrder(0, SL, TP);
       }
      
    }
     
   
    
    
      if (BS2>0 && BSW1_2>0 && BSW2_2>0)
      {        
       if (Rs<=MaxRast)
       {int ticket = OpenPosition(Symbol(), OP_SELL, Lot); 

       SL = NormalizeDouble(BS2+(Otstup*Point), Digits);
       TP = NormalizeDouble(Bid - (((SL - Bid)/Point)*Point)*multiplerTP, Digits);
       ModifyOrder(0, SL, TP);

       
       }
       if (Rs>MaxRast)
       {int ticket = OpenPosition(Symbol(), OP_SELL, Lot); 


       SL = NormalizeDouble(BS2+(Otstup*Point), Digits);
       TP = NormalizeDouble(Bid - (((SL - Bid)/Point)*Point)*multiplerTP, Digits);
       ModifyOrder(0, SL, TP);
       

       }
      }
    }
     
   
} 
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
// Функции.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 06.03.2008                                                     |
//|  Описание : Возвращает флаг существования позиций                          |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время открытия)           |
//+----------------------------------------------------------------------------+
bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.09.2005                                                     |
//|  Описание : Возвращает наименование торговой операции                      |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    op - идентификатор торговой операции                                    |
//+----------------------------------------------------------------------------+
string GetNameOP(int op) {
  switch (op) {
    case OP_BUY      : return("Buy");
    case OP_SELL     : return("Sell");
    case OP_BUYLIMIT : return("Buy Limit");
    case OP_SELLLIMIT: return("Sell Limit");
    case OP_BUYSTOP  : return("Buy Stop");
    case OP_SELLSTOP : return("Sell Stop");
    default          : return("Unknown Operation");
  }
}

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.09.2005                                                     |
//|  Описание : Возвращает наименование таймфрейма                             |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    TimeFrame - таймфрейм (количество секунд)      (0 - текущий ТФ)         |
//+----------------------------------------------------------------------------+
string GetNameTF(int TimeFrame=0) {
  if (TimeFrame==0) TimeFrame=Period();
  switch (TimeFrame) {
    case PERIOD_M1:  return("M1");
    case PERIOD_M5:  return("M5");
    case PERIOD_M15: return("M15");
    case PERIOD_M30: return("M30");
    case PERIOD_H1:  return("H1");
    case PERIOD_H4:  return("H4");
    case PERIOD_D1:  return("Daily");
    case PERIOD_W1:  return("Weekly");
    case PERIOD_MN1: return("Monthly");
    default:                 return("UnknownPeriod");
  }
}

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.09.2005                                                     |
//|  Описание : Вывод сообщения в коммент и в журнал                           |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    m - текст сообщения                                                     |
//+----------------------------------------------------------------------------+
void Message(string m) {
  Comment(m);
  if (StringLen(m)>0) Print(m);
}

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 28.11.2006                                                     |
//|  Описание : Модификация одного предварительно выбранного ордера.           |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    pp - цена установки ордера                                              |
//|    sl - ценовой уровень стопа                                              |
//|    tp - ценовой уровень тейка                                              |
//|    cl - цвет значка модификации                                            |
//+----------------------------------------------------------------------------+
void ModifyOrder(double pp=-1, double sl=0, double tp=0, color cl=CLR_NONE) {
  bool   fm;
  double op, pa, pb, os, ot;
  int    dg=MarketInfo(OrderSymbol(), MODE_DIGITS), er, it;

  if (pp<=0) pp=OrderOpenPrice();
  if (sl<0 ) sl=OrderStopLoss();
  if (tp<0 ) tp=OrderTakeProfit();
  
  pp=NormalizeDouble(pp, dg);
  sl=NormalizeDouble(sl, dg);
  tp=NormalizeDouble(tp, dg);
  op=NormalizeDouble(OrderOpenPrice() , dg);
  os=NormalizeDouble(OrderStopLoss()  , dg);
  ot=NormalizeDouble(OrderTakeProfit(), dg);

  if (pp!=op || sl!=os || tp!=ot) {
    for (it=1; it<=NumberOfTry; it++) {
      if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
      while (!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      fm=OrderModify(OrderTicket(), pp, sl, tp, 0, cl);
      if (fm) {
        if (UseSound) PlaySound(NameFileSound); break;
      } else {
        er=GetLastError();
        pa=MarketInfo(OrderSymbol(), MODE_ASK);
        pb=MarketInfo(OrderSymbol(), MODE_BID);
        Print("Error(",er,") modifying order: ",ErrorDescription(er),", try ",it);
        Print("Ask=",pa,"  Bid=",pb,"  sy=",OrderSymbol(),
              "  op="+GetNameOP(OrderType()),"  pp=",pp,"  sl=",sl,"  tp=",tp);
        Sleep(1000*10);
      }
    }
  }
}

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 21.03.2008                                                     |
//|  Описание : Открывает позицию и возвращает её тикет.                       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (NULL или "" - текущий символ)          |
//|    op - операция                                                           |
//|    ll - лот                                                                |
//|    sl - уровень стоп                                                       |
//|    tp - уровень тейк                                                       |
//|    mn - MagicNumber                                                        |
//+----------------------------------------------------------------------------+
int OpenPosition(string sy, int op, double ll, double sl=0, double tp=0, int mn=0) {
  color    clOpen;
  datetime ot;
  double   pp, pa, pb;
  int      dg, err, it, ticket=0;
  string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

  if (sy=="" || sy=="0") sy=Symbol();
  if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell;
  for (it=1; it<=NumberOfTry; it++) {
    if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
      Print("OpenPosition(): Остановка работы функции");
      break;
    }
    while (!IsTradeAllowed()) Sleep(5000);
    RefreshRates();
    dg=MarketInfo(sy, MODE_DIGITS);
    pa=MarketInfo(sy, MODE_ASK);
    pb=MarketInfo(sy, MODE_BID);
    if (op==OP_BUY) pp=pa; else pp=pb;
    pp=NormalizeDouble(pp, dg);
    ot=TimeCurrent();
    ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, 0, clOpen);
    if (ticket>0) {
      if (UseSound) PlaySound(NameFileSound); break;
    } else {
      err=GetLastError();
      if (pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy);
      // Вывод сообщения об ошибке
      Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it);
      Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
            " pp=",pp," sl=",sl," tp=",tp," mn=",mn);
      // Блокировка работы советника
      if (err==2 || err==64 || err==65 || err==133) {
        gbDisabled=True; break;
      }
      // Длительная пауза
      if (err==4 || err==131 || err==132) {
        Sleep(1000*300); break;
      }
      if (err==128 || err==142 || err==143) {
        Sleep(1000*66.666);
        if (ExistPositions(sy, op, mn, ot)) {
          if (UseSound) PlaySound(NameFileSound); break;
        }
      }
      if (err==140 || err==148 || err==4110 || err==4111) break;
      if (err==141) Sleep(1000*100);
      if (err==145) Sleep(1000*17);
      if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
      if (err!=135) Sleep(1000*7.7);
    }
  }
  return(ticket);
}
//+----------------------------------------------------------------------------+
double LotsByRisk (double risk, double sl)
{
 double lot_min = MarketInfo(Symbol(), MODE_MINLOT);
 double lot_max = MarketInfo(Symbol(), MODE_MAXLOT);
 double lot_step = MarketInfo(Symbol(), MODE_LOTSTEP);
 double lotcoast = MarketInfo(Symbol(), MODE_TICKVALUE);
 
 
 double lot = AccountBalance() * risk/100;
 double UsdPerPip = lot/sl;
 
 lot = NormalizeDouble(UsdPerPip/lotcoast, 2);
 lot = NormalizeDouble(lot/lot_step, 0) * lot_step;
 
 if (lot < lot_min) lot = lot_min;
 if (lot > lot_max) lot = lot_max;
 
  return(lot);
}
//+----------------------------------------------------------------------------+
int CloseAllPos()
{
for(int i=0;i<OrdersTotal();i++){
if(true==OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{if(OrderSymbol()==Symbol())
{ if(OrderType()==OP_BUY){OrderClose(OrderTicket(),OrderLots(),Bid,Yellow);i--;}
  if(OrderType()==OP_SELL){OrderClose(OrderTicket(),OrderLots(),Ask,Yellow);i--;}
}}
}// end for
//=====
return(0);
}
//+------------------------------------------------------------------+
void BU()
{
   for(int i=0; i<OrdersTotal(); i++) 
      {
       if(OrderSelect(i, SELECT_BY_POS))
        {
        if(OrderSymbol()==Symbol())
         {      
         if(OrderType()==OP_BUY) 
          {
           if(OrderOpenPrice()<=(Bid-BULevel*Point)&&OrderOpenPrice()>OrderStopLoss())
            {      
             OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
            }
           }
                 
 
         if(OrderType() == OP_SELL) 
           {
            if(OrderOpenPrice()>=(Ask+BULevel*Point)&&OrderOpenPrice()<OrderStopLoss()) 
             {
              OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Red);
             }
           } 
         }
       }
      }
}
//------------------------------------------------------------------+
 
это насчёт 4108, в коде ордер не выбирается нигде, надо явно выбирать, там в другой функции написано, как это делать (в функции закрытия, например)
//|  Версия   : 28.11.2006                                                     |
//|  Описание : Модификация одного предварительно выбранного ордера.           |

ну и бабла побольше надо, во избежание 134.


 
evillive:

ну и бабла побольше надо, во избежание 134.



134 походу возникает из-за неработающего манименеджмента. Просто размер стоплосса это разница между ценой и индикатором. Насчет модификации:

if (ticket>0)

{Modify();} 

 

Тут разве выбирается ордер? Просто в других моих советниках написано именно так. Я попробовал и в этом, но возникает такая-же ошибка.

 
Hurricanas:


134 походу возникает из-за неработающего манименеджмента. Просто размер стоплосса это разница между ценой и индикатором. Насчет модификации:

if (ticket>0)

{Modify();} 

 

Тут разве выбирается ордер? Просто в других моих советниках написано именно так. Я попробовал и в этом, но возникает такая-же ошибка.


134 возникает из-за нехватки средств на открытие, причём тут стоплосс?


А ордер в данном коде не выбирается, но надо бы.

 
evillive:

134 возникает из-за нехватки средств на открытие, причём тут стоплосс?


А ордер не выбирается, но надо бы.


 Я имею ввиду что лот зависит от размера стоп-лосса, стоп-лосс определяется разницей положения цены и индикатора. Т.е. когда возникает ошибка 134, это значит что советник пытается влупить гигантский лот. Размер стопа определяется здесь.
          if (Rb<=MaxRast)
       {
       SL = NormalizeDouble(BS1-(Otstup*Point), Digits);
       Stop = ((Ask - SL)/Point)*Point;
       }
       
          if (Rb>MaxRast)
       {
       SL = NormalizeDouble(TMA1-(Otstup*Point), Digits);
       Stop = ((Ask - SL)/Point)*Point;       
       }
       
          if (Rs<=MaxRast)
       {
       SL = NormalizeDouble(BS2+(Otstup*Point), Digits);
       Stop = ((SL - Bid)/Point)*Point;
       }
       
          if (Rs>MaxRast)
       {
       SL = NormalizeDouble(TMA2+(Otstup*Point), Digits);
       Stop = ((SL - Bid)/Point)*Point;
       }
 
Hurricanas:

 Я имею ввиду что лот зависит от размера стоп-лосса, стоп-лосс определяется разницей положения цены и индикатора. Т.е. когда возникает ошибка 134, это значит что советник пытается влупить гигантский лот. Размер стопа определяется здесь.

то есть при гигантском стоплоссе - чудовищный лот )))

советую пересмотреть стратегию ММ, а лучше бросить форекс, разорение одно ;)


З.Ы.: в коде лот делится на стоплосс, значит расчётный стоплосс очень мелкий получается и в результате лот максимальный. запринтуйте все результаты расчётов, не ленитесь, тогда увидите где ошибочка.

 
evillive:

то есть при гигантском стоплоссе - чудовищный лот )))

советую пересмотреть стратегию ММ, а лучше бросить форекс, разорение одно ;)


З.Ы.: в коде лот делится на стоплосс, значит расчётный стоплосс очень мелкий получается и в результате лот максимальный. запринтуйте все результаты расчётов, не ленитесь, тогда увидите где ошибочка.



Спасибо, попробую! =) Я сам как-то не догадался принтовать результаты, всегда без этого обходился.

По поводу выбора ордера вы были правы, исправил, осталась только одна ошибка. 

Насчет "бросить форекс". Уже два года здесь, назад пути нет - без прибыли не уйду! =) 

 
evillive:

то есть при гигантском стоплоссе - чудовищный лот )))

советую пересмотреть стратегию ММ, а лучше бросить форекс, разорение одно ;)


З.Ы.: в коде лот делится на стоплосс, значит расчётный стоплосс очень мелкий получается и в результате лот максимальный. запринтуйте все результаты расчётов, не ленитесь, тогда увидите где ошибочка.



Я понял в чём ошибка. Я не могу правильно расчитать разницу цен в пунктах. А как же это сделать?

  // Рассчитываем расстояние между индикаторами.
  if (TMA1>BS1){Rb = ((TMA1 - BS1)/Point)*Point;}


   // и
  if (TMA1>BS1){Rb = ((TMA1 - BS1)/Point);}

 Не являются правильными вариантами, хотя в другом советнике первый работает безотказно. 

 
Hurricanas:


Я понял в чём ошибка. Я не могу правильно расчитать разницу цен в пунктах. А как же это сделать?

 Не являются правильными вариантами, хотя в другом советнике первый работает безотказно. 


приведите пример значений индикаторов
 
evillive:

приведите пример значений индикаторов

Да, забыл. Вы сможете помочь, если не сложно? Или материала на эту тему подкиньте, я был бы вам очень признателен. А то я не могу найти инфу в интернете. Индикаторы показывают цены, на которых находятся, например: 1.3055 

 

если значения обоих индикаторов близки к цене, тогда разницу в пунктах вычислить можно так:

if (TMA1>BS1) Rb = MathAbs((TMA1 - BS1)/Point); //(1.3356-1.3297)/0.0001=59)
Причина обращения: