Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 64

 
Leser: Подскажите как и где указать в советнике принадлежность МА к окну №2. К примеру к MFI добавил МА и этот МА хочу прописать в советнике. Не знаю как и где.
А подробнее? У Вас советник уже использует индикатор MFI, и Вам теперь требуется, чтобы он использовал второй индикатор - индикатор МА? Или же советник пока вообще не использует индикаторы, а Вам надо, чтобы он использовал индикатор МА?
 
Yedelkin:

1. Я бы сказал так: использовать чужой код следует с большой долей осторожности. Потому что чужой код - это и чужие ошибки.

2. Вот здесь (https://www.mql5.com/ru/forum/6343/page64#comment_357008) я предложил Вам попробовать правильно обнулить переменные перед их использованием. Но в Вашем коде это предложение пока не реализовано. Более, того, в коде присутствуют конструкции вот такого типа:

Понимаете, в этой конструкции переменные  request и result обнуляются не перед использованием, а после использования. Более, того, после обнуления этих локальных переменных функция прекращает свою работу, то есть само такое обнуление является бессмысленным. Иными словами, такая конструкция является наглядным примером того, как не надо проводить обнуление переменных типа MqlTradeRequest и MqlTradeResult. Поэтому, если есть желание, попробуйте всё-таки обнулить переменные правильно. Если что-то не получится, подробно опишите, что именно "не работает".

3. В Стандартной библиотеке есть  торговый класс "Справочник MQL5 / Стандартная библиотека / Торговые классы / CTrade". Попробуйте разобраться, как применять его на практике. На начальном этапе погружения в язык этот класс может оказаться вполне достаточным. Например, в этом классе есть вот такой метод: "Справочник MQL5 / Стандартная библиотека / Торговые классы / 2CTrade / PositionModify". Реализован он так:

В нём строчка  'ClearStructures();'  как раз и обнуляет переменную m_request перед её использованием.

Yedelkin,

Болшое спосибо :)

Посмотрел,увидел свою ошибку.

Можно написат так:

//+------------------------------------------------------------------+
//| Clear structures request,result and check_result                 |
//+------------------------------------------------------------------+
void ClearStructures()
  {
   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check_result;
   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check_result);
  } 

Но мне понравилос Вашие предложения:

   MqlTradeRequest request={0};
   MqlTradeResult result={0};
Все равно-резултата одинаковие.

Счас позиция не находит-буду мучатся с етой задачи.

Спосибо. 

 

Yedelkin,

Пишу Вам,потому что адекватно отвечаете.

Два сорса-МТ4 и МТ5.

Почему не работает на МТ5-они же одинаковие. 

Файлы:
MTB_1E.mq4  4 kb
MTB_E.mq5  9 kb
 
mario065: Два сорса-МТ4 и МТ5. Почему не работает на МТ5-они же одинаковие. 

 К сожалению, совершенно не разбираюсь в МТ4. Посмотрю, и если смогу уловить что-нибудь - отпишусь.

Дополнение. В общем, Вы дождитесь открытия рынка и отпишитесь, что именно должно было сработать, но не сработало. 

 
Yedelkin:

 К сожалению, совершенно не разбираюсь в МТ4. Посмотрю, и если смогу уловить что-нибудь - отпишусь.

Дополнение. В общем, Вы дождитесь открытия рынка и отпишитесь, что именно должно было сработать, но не сработало. 

Так ето я делаю про себя-и кому если нужно.

Вот и коментарии:

Если указание пипс болше нуля для модификация-за два язика(МТ4 и МТ5):

if(TradeTrailing>0)

if(MStop > 0)

 Если ети пипси (Бид - пипс)болше опен позишон:

if((NormalizeDouble(Bid, Digits)-TradeTrailing)>=OrderOpenPrice())

if(NormalizeDouble(Bid - MStop,4) >= Open)
Если стоп = 0 или Бид - пипси дял трейлинг >= от Опен посишон + определение пипс:
if(OrderStopLoss()==0 || (NormalizeDouble(Bid, Digits)-TradeTrailing)>=(OrderStopLoss()+0.0005))

if(SL == 0 || NormalizeDouble(Bid - MStop,4) >= NormalizeDouble(SL + MStop,4))

модификация:

ОrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid, Digits)-TradeTrailing,OrderTakeProfit(),0,Blue);

ModifyPosition(Symbol(),NormalizeDouble(Bid - MStop,4),TP);

Вот и все.

Хочу сделат отделная функция для модификация. 

 
Yedelkin:
А подробнее? У Вас советник уже использует индикатор MFI, и Вам теперь требуется, чтобы он использовал второй индикатор - индикатор МА? Или же советник пока вообще не использует индикаторы, а Вам надо, чтобы он использовал индикатор МА?
Советник использует MFI, но не могу понять как записать индикатор МА! Главное условие - это местонахождение МА. Ма находиться не на графике (окно №1), а в окне с индикатором MFI (окно №2).
 
Leser: Советник использует MFI, но не могу понять как записать индикатор МА! Главное условие - это местонахождение МА. Ма находиться не на графике (окно №1), а в окне с индикатором MFI (окно №2).

Если советник использует MFI, то его код должен содержать строчку с получением хендла вот этого индикатора: "Справочник MQL5 / Технические индикаторы / iMFI ". Соответственно, получение хендла  индикатора скользящего среднего описано здесь: "Справочник MQL5 / Технические индикаторы / iMA ".

Попробуйте также ознакомиться со статьёй "Индикатор от индикатора в MQL5". 

 
mario065: Вот и коментарии: Если указание пипс болше нуля для модификация-за два язика(МТ4 и МТ5):  Если ети пипси (Бид - пипс)болше опен позишон:Если стоп = 0 или Бид - пипси дял трейлинг >= от Опен посишон + определение пипс: модификация: Вот и все. Хочу сделат отделная функция для модификация. 

1. К сожалению, Вы так и не указали, что именно "не работает". Т.е. Вы изложили логику работы программы (как она должна работать), но не указали, где логика работы программы нарушается, и в чём именно эти нарушения выражаются. Без подробного описания проблемы остаётся только сделать замечания по коду.

2. В функции bool ModifyPosition(const string symbol,double StopLoss,double Takeprofit) есть такие строчки:

   if(!OrderSend(request,result) || result.deal==0)
     {
      Print("Modify error =", GetLastError());
      return(false);
     }

Если посмотрите описание структуры MqlTradeResult, то увидите, что поле deal описано следующим образом:

deal

Тикет сделки, если она совершена. Сообщается при торговой операции TRADE_ACTION_DEAL

Поскольку Ваша функция  ModifyPosition() осуществляет совершенно иную операцию, значение result.deal должно быть всегда равным нулю. Следовательно, оператор
if(!OrderSend(request,result) || result.deal==0)

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

2. Смотрим на строчки из предыдущего пункта 2. Вы там используете  функцию GetLastError(), которая предназначена возвращать код последней ошибки. Но Вы совершенно не обнуляете перед использованием переменную, которая содержит код ошибки, поэтому даже в случае успешной модификации у Вас выводится на печать ошибка, которая могла произойти задолго до отправки запроса на модификацию позиции. Надо примерно так:

ResetLastError();   
if(!OrderSend(request,result))
   { 
    ... 
    Print("Modify error =", GetLastError());
    ...
   }

3. Посмотрите вот на эти строчки:

          if(SL == 0 || NormalizeDouble(Bid - MStop,4) >= SL) 
           {
            ModifyPosition(Symbol(),NormalizeDouble(Bid - MStop,4),TP);
           }

Допустим, на очередном тике у Вас сработало условие NormalizeDouble(Bid - MStop,4) == SL. Допустим, что при этом SL==1.11110. Но тогда и  ModifyPosition(Symbol(),1.11110,TP). Т.е. при такой  модификации будут указаны уже установленные ранее уровни.

А что произойдёт, если на следующем тике равенство NormalizeDouble(Bid - MStop,4) == SL опять сработает?  :) Особенно если учесть, что (а) нормализация проводится по четырём разрядам при возможном наличии пятизначных котировок, (б) торговые запросы могут выполнятся на сервере с некоторой задержкой.  

4. Есть ещё такое свойство символа, как SYMBOL_TRADE_STOPS_LEVEL. Но у Вас в коде отсутствует проверка этого уровня. Т.е., если  кандидата на новый стоп-лосс для Buy-позиции обозначить как SL_new, то было бы не лишним проверять условие типа if(Bid-STOPS_LEVEL>SL_new).

 

Да, и вообще, попробуйте посмотреть Справочник на предмет сравнения вещественных чисел. Насколько я помню, там категорически не рекомендуется сравнивать два вещественных числа вот таким вот образом: if(double_1 == double_2).

 

Yedelkin,

Болшое спосибо.Решетов тоже показал где ошибка.

Вот сама функция:

//+------------------------------------------------------------------+
//| Modify position.                                                 |
//+------------------------------------------------------------------+
bool ModifyPosition(const string symbol,double StopLoss,double Takeprofit){
//---- обявяване на структурата и резултата на търговското искане
   MqlTradeRequest request={0};
   MqlTradeResult result={0};
//---- структурна инициализация на  търговското искане MqlTradeRequest за модифициране на  позиция
   request.action       = TRADE_ACTION_SLTP;
   request.symbol       = symbol;
   request.sl           = StopLoss;
   request.tp           = Takeprofit;
   string word          = "";
   StringConcatenate(word,
                     "<<< ============ Modifyposition():   Модифицираме позицията  ",
                     symbol," ============ >>>");
   Print(word);
//---- модифицираме позицията и  проверяваме резултата от търговското искане
   if(!OrderSend(request,result))
     {
      Print("Modify error =", GetLastError());
      return(false);
     }
   return(true);
  }

А вот икак надо било сделат сам визов функции:

  double buy_trail = 0;
  double sel_trail = 0;
  double SL,TP,Open;
  if(PositionSelect(Symbol())){
    if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
      {
      Open = PositionGetDouble(POSITION_PRICE_OPEN);
      SL   = PositionGetDouble(POSITION_SL);
      TP   = PositionGetDouble(POSITION_TP);
      Bid  = SymbolInfoDouble(Symbol(),SYMBOL_BID);
      buy_trail = NormalizeDouble(Bid - Open,Digits());
      if(buy_trail > MStop)
       {
        if(NormalizeDouble((Bid - MStop),Digits()) >= Open && Open > SL)
          {
           ModifyPosition(Symbol(),Open,TP);
          }
          if(NormalizeDouble((Bid - MStop),Digits()) > SL && Open <= SL)
           {
            ModifyPosition(Symbol(),NormalizeDouble((SL + 0.001),Digits()),TP);
           }
        }
      }
    if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
      {
      Open = PositionGetDouble(POSITION_PRICE_OPEN);
      SL   = PositionGetDouble(POSITION_SL);
      TP   = PositionGetDouble(POSITION_TP);
      Ask  = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
      sel_trail = NormalizeDouble(Open - Ask,Digits());
      if(sel_trail > MStop)
       { 
        if(NormalizeDouble((Ask + MStop),Digits()) <= Open && Open < SL)
          {
           ModifyPosition(Symbol(),Open,TP);
          }
          if(NormalizeDouble((Ask + MStop),Digits()) < SL && Open >= SL)
           {
            ModifyPosition(Symbol(),NormalizeDouble((SL - 0.001),Digits()),TP);
           }
        }
      }
     }

Счас все работает нормално.

Спосибо. 

Причина обращения: