Questions des débutants MQL5 MT5 MetaTrader 5 - page 200

 

Lors du débogage, l'EA se bloque, bien qu'en théorie, il devrait effectuer un cycle dans OnTIck jusqu'à ce que la condition Tik==0 devienne fausse.

 //+------------------------------------------------------------------+
//|                                                         USSR.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property version    "1.00"
#include <Trade\Trade.mqh>


//--- input parameters
// Входные параметры
input int       StopLoss= 15 ;       // Stop Loss
input int       TakeProfit= 30 ;   // Take Profit
input int       ADX_Period= 8 ;     // Период ADX
input int       MA_Period= 8 ;       // Период Moving Average
input int       EA_Magic= 12345 ;   // Magic Number советника
input double    Adx_Min= 22.0 ;     // Минимальное значение ADX
input double    Lot= 0.01 ;         // Количество лотов для торговли
//--- глобальные переменные
int tik= 0 ;
int adxHandle; // хэндл индикатора ADX
int maHandle;   // хэндл индикатора Moving Average
double plsDI[],minDI[],adxVal[]; // динамические массивы для хранения численных значений +DI, -DI и ADX для каждого бара
double maVal[]; // динамический массив для хранения значений индикатора Moving Average для каждого бара
double p_close; // переменная для хранения значения close бара
int STP,TKP; // будут использованы для значений Stop Loss и Take Profit
int TrailingStop=TakeProfit;
double Bid;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
//Инациализация советника
int OnInit ()
  {
//--- Получить хэндл индикатора ADX
   adxHandle= iADX ( NULL , 0 ,ADX_Period);
//--- Получить хэндл индикатора Moving Average
   maHandle= iMA ( _Symbol , _Period ,MA_Period, 0 , MODE_EMA , PRICE_CLOSE );
//--- Нужно проверить, не были ли возвращены значения Invalid Handle
   if (adxHandle< 0 || maHandle< 0 )
     {
       Alert ( "Ошибка при создании индикаторов - номер ошибки: " , GetLastError (), "!!" );
       return (- 1 );
     }

   STP = StopLoss;
   TKP = TakeProfit;
   if ( _Digits == 5 || _Digits == 3 )
     {
      STP = STP* 10 ;
      TKP = TKP* 10 ;
     }
   return ( 0 );
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
//Выключение советника
void OnDeinit ( const int reason)
  {
   IndicatorRelease (adxHandle);
   IndicatorRelease (maHandle);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
//Обработка событий
void OnTick ()
  {
   while (tik== 0 )
     {
       //--- Достаточно ли количество баров для работы
       if ( Bars ( _Symbol , _Period )< 60 ) // общее количество баров на графике меньше 60?
        {
         Alert ( "На графике меньше 60 баров, советник не будет работать!!" );
         return ;
        }

       // Для сохранения значения времени бара мы используем static-переменную Old_Time.
       // При каждом выполнении функции OnTick мы будем сравнивать время текущего бара с сохраненным временем.
       // Если они не равны, это означает, что начал строится новый бар.

       static datetime Old_Time;
       datetime New_Time[ 1 ];
       bool IsNewBar= false ;

       // копируем время текущего бара в элемент New_Time[0]
       int copied= CopyTime ( _Symbol , _Period , 0 , 1 ,New_Time);
       if (copied> 0 ) // ok, успешно скопировано
        {
         if (Old_Time!=New_Time[ 0 ]) // если старое время не равно
           {
            IsNewBar= true ;   // новый бар
             if ( MQL5InfoInteger ( MQL5_DEBUGGING )) Print ( "Новый бар" ,New_Time[ 0 ], "старый бар" ,Old_Time);
            Old_Time=New_Time[ 0 ];   // сохраняем время бара
           }
        }
       else
        {
         Alert ( "Ошибка копирования времени, номер ошибки =" , GetLastError ());
         ResetLastError ();
         return ;
        }

       //--- советник должен проверять условия совершения новой торговой операции только при новом баре
       if (IsNewBar== false )
        {
         return ;
        }

       //--- Имеем ли мы достаточное количество баров на графике для работы
       int Mybars= Bars ( _Symbol , _Period );
       if (Mybars< 60 ) // если общее количество баров меньше 60
        {
         Alert ( "На графике менее 60 баров, советник работать не будет!!" );
         return ;
        }

       //--- Объявляем структуры, которые будут использоваться для торговли
       MqlTick latest_price;       // Будет использоваться для текущих котировок
       MqlTradeRequest mrequest;     // Будет использоваться для отсылки торговых запросов
       MqlTradeResult mresult;       // Будет использоваться для получения результатов выполнения торговых запросов
       MqlRates mrate[];           // Будет содержать цены, объемы и спред для каждого бара
       ZeroMemory (mrequest);
/*
     Установим индексацию в массивах котировок и индикаторов 
     как в таймсериях
*/
       // массив котировок
       ArraySetAsSeries (mrate, true );
       // массив значений индикатора ADX DI+
       ArraySetAsSeries (plsDI, true );
       // массив значений индикатора ADX DI-
       ArraySetAsSeries (minDI, true );
       // массив значений индикатора ADX
       ArraySetAsSeries (adxVal, true );
       // массив значений индикатора MA-8
       ArraySetAsSeries (maVal, true );

       //--- Получить текущее значение котировки в структуру типа MqlTick
       if (! SymbolInfoTick ( _Symbol ,latest_price))
        {
         Alert ( "Ошибка получения последних котировок - ошибка:" , GetLastError (), "!!" );
         return ;
        }

       //--- Получить исторические данные последних 3-х баров
       if ( CopyRates ( _Symbol , _Period , 0 , 3 ,mrate)< 0 )
        {
         Alert ( "Ошибка копирования исторических данных - ошибка:" , GetLastError (), "!!" );
         return ;
        }

       //--- Используя хэндлы индикаторов, копируем новые значения индикаторных буферов в массивы
       if ( CopyBuffer (adxHandle, 0 , 0 , 3 ,adxVal)< 0 || CopyBuffer (adxHandle, 1 , 0 , 3 ,plsDI)< 0
         || CopyBuffer (adxHandle, 2 , 0 , 3 ,minDI)< 0 )
        {
         Alert ( "Ошибка копирования буферов индикатора ADX - номер ошибки:" , GetLastError (), "!!" );
         return ;
        }
       if ( CopyBuffer (maHandle, 0 , 0 , 3 ,maVal)< 0 )
        {
         Alert ( "Ошибка копирования буферов индикатора Moving Average - номер ошибки:" , GetLastError ());
         return ;
        }
       //--- есть ли открытые позиции?
       bool Buy_opened= false ;   // переменные, в которых будет храниться информация 
       bool Sell_opened= false ; // о наличии соответствующих открытых позиций

       if ( PositionSelect ( _Symbol )== true ) // есть открытая позиция
        {
         if ( PositionGetInteger ( POSITION_TYPE )== POSITION_TYPE_BUY )
           {
            Buy_opened= true ;   // это длинная позиция
           }
         else if ( PositionGetInteger ( POSITION_TYPE )== POSITION_TYPE_SELL )
           {
            Sell_opened= true ; // это короткая позиция
           }
        }
       // Скопируем текущую цену закрытия предыдущего бара (это бар 1)
      p_close=mrate[ 1 ].close;   // цена закрытия предыдущего бара
/*
    1. Проверка условий для покупки : MA-8 растет, 
    предыдущая цена закрытия бара больше MA-8, ADX > 22, +DI > -DI
*/
       //--- объявляем переменные типа boolean, они будут использоваться при проверке условий для покупки
       bool Buy_Condition_1=(maVal[ 0 ]>maVal[ 1 ]) && (maVal[ 1 ]>maVal[ 2 ]); // MA-8 растет
       bool Buy_Condition_2 = (p_close > maVal[ 1 ]);         // предыдущая цена закрытия выше скользяшей средней MA-8
       bool Buy_Condition_3 = (adxVal[ 0 ]>Adx_Min);           // текущее значение ADX больше, чем минимальное (22)
       bool Buy_Condition_4 = (plsDI[ 0 ]>minDI[ 0 ]);           // +DI больше, чем -DI

       //--- собираем все вместе
       if (Buy_Condition_1 && Buy_Condition_2)
        {
         if (Buy_Condition_3 && Buy_Condition_4)
           {
             // есть ли в данный момент открытая позиция на покупку?
             if (Sell_opened)
              {
               Alert ( "Уже есть позиция на покупку !!!" );
               return ; // не добавлять к открытой позиции на покупку
              }
            mrequest.action = TRADE_ACTION_DEAL ;                                 // немедленное исполнение
            mrequest.price = NormalizeDouble (latest_price.ask, _Digits );           // последняя цена ask
            mrequest.sl = NormalizeDouble (latest_price.ask + STP* _Point , _Digits ); // Stop Loss
            mrequest.tp = NormalizeDouble (latest_price.ask - TKP* _Point , _Digits ); // Take Profit
            mrequest.symbol= _Symbol ;                                         // символ
            mrequest.volume = Lot;                                             // количество лотов для торговли
            mrequest.magic = EA_Magic;                                         // Magic Number
            mrequest.type= ORDER_TYPE_SELL ;                                     // ордер на покупку
            mrequest.type_filling = ORDER_FILLING_FOK ;                           // тип исполнения ордера - все или ничего
            mrequest.deviation= 100 ;                                           // проскальзывание от текущей цены
             //--- отсылаем ордер
             OrderSend (mrequest,mresult);
             // анализируем код возврата торгового сервера
             if (mresult.retcode== 10009 || mresult.retcode== 10008 ) // запрос выполнен или ордер успешно помещен
              {
               int tik=mresult.order;
               Alert ( "Ордер Buy успешно помещен, тикет ордера #:" ,mresult.order, "!!" );
              }
             else
              {
               Alert ( "Запрос на установку ордера Buy не выполнен - код ошибки:" , GetLastError ());
               return ;
              }
           }
        }
/*
    2. Проверка условий для продажи : MA-8 падает, 
    предыдущая цена закрытия бара меньше MA-8, ADX > 22, -DI > +DI
*/
       //--- объявляем переменные типа boolean, они будут использоваться при проверке условий для продажи
       bool Sell_Condition_1 = (maVal[ 0 ]<maVal[ 1 ]) && (maVal[ 1 ]<maVal[ 2 ]);   // MA-8 падает
       bool Sell_Condition_2 = (p_close <maVal[ 1 ]);                         // предыдущая цена закрытия ниже MA-8
       bool Sell_Condition_3 = (adxVal[ 0 ]>Adx_Min);                         // текущее значение ADX value больше заданного (22)
       bool Sell_Condition_4 = (plsDI[ 0 ]<minDI[ 0 ]);                         // -DI больше, чем +DI

       //--- собираем все вместе
       if (Sell_Condition_1 && Sell_Condition_2)
        {
         if (Sell_Condition_3 && Sell_Condition_4)
           {
             // есть ли в данный момент открытая позиция на продажу?
             if (Buy_opened)
              {
               Alert ( "Уже есть позиция на продажу!!!" );
               return ; // не добавлять к открытой позиции на продажу
              }
            mrequest.action= TRADE_ACTION_DEAL ;                                 // немедленное исполнение
            mrequest.price= NormalizeDouble (latest_price.bid, _Digits );           // последняя цена Bid
            mrequest.sl = NormalizeDouble (latest_price.bid - STP* _Point , _Digits ); // Stop Loss
            mrequest.tp = NormalizeDouble (latest_price.bid + TKP* _Point , _Digits ); // Take Profit
            mrequest.symbol= _Symbol ;                                         // символ
            mrequest.volume = Lot;                                             // количество лотов для торговли
            mrequest.magic = EA_Magic;                                         // Magic Number
            mrequest.type= ORDER_TYPE_BUY ;                                     // ордер на продажу
            mrequest.type_filling= ORDER_FILLING_FOK ;                           // тип исполнения ордера - все или ничего
            mrequest.deviation= 100 ;                                           // проскальзывание от текущей цены
             //--- отсылаем ордер
             OrderSend (mrequest,mresult);
             // получаем код ответа торгового сервера
             if (mresult.retcode== 10009 || mresult.retcode== 10008 ) // запрос выполнен или ордер успешно помещен
              {
               int tik=mresult.order;
               Alert ( "Ордер Sell успешно помещен, тикет ордера #:" ,mresult.order, "!!" );
              }
             else
              {
               Alert ( "Запрос на установку ордера Sell не выполнен - код ошибки:" , GetLastError ());
               return ;
              }
           }
        }
     }
   return ;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart ()
  {
   if (tik== 0 ){ OnInit (); OnTick ();}
   else
     {
       if (TrailingStop> 0 )
        {
         if ( OrderSelect (tik)== true )
           {
             if ( ORDER_TYPE_BUY )
              {
               if (Bid- ORDER_PRICE_OPEN > _Point *(TrailingStop/ 10 ))
                 {
                   if ( ORDER_SL <Bid- _Point *(TrailingStop/ 10 ))
                    {
                     bool Ans=trade.OrderModify(tik, ORDER_PRICE_OPEN , NormalizeDouble (Bid- _Point *(TrailingStop/ 10 ), 5 ), ORDER_TP , ORDER_TIME_GTC , ORDER_TIME_EXPIRATION );
                     if (Ans== true )
                       {
                         Alert ( "Цена Stop Loss ордера успешно модифицирована." );
                         return ;
                       }
                    }
                 }
              }

             if ( ORDER_TYPE_SELL )
              {
               if (Bid- ORDER_PRICE_OPEN < _Point *- 1 *(TrailingStop/ 10 ))
                 {
                   if ( ORDER_SL >Bid- _Point *(TrailingStop/ 10 ))
                    {
                     bool Ans=trade.OrderModify(tik, ORDER_PRICE_OPEN , NormalizeDouble (Bid- _Point *(TrailingStop/ 10 ), 5 ), ORDER_TP , ORDER_TIME_GTC , ORDER_TIME_EXPIRATION );
                     if (Ans== true )
                       {
                         Alert ( "Цена Stop Loss ордера успешно модифицирована." );
                         return ;
                       }
                    }
                 }
              }
           }

        }
     }
   return ;
  }

//+------------------------------------------------------------------+
 
StrangerNet:

Lors du débogage, le conseiller expert se bloque, alors qu'en principe il doit exécuter une boucle dans OnTIck jusqu'à ce que la condition Tik==0 devienne fausse.

Recherchez les erreurs. Lors de la compilation, faites attention au message d'erreur.

declaration of 'tik' hides global declaration at line 23        test.mq5        223     20

indique que vous essayez de créer une variable et que la variable existe déjà dans les déclarations globales.

Et ainsi de suite.

 
Harigal:

Bonjour ! J'ai maîtrisé MQL4 il y a un an avec facilité. Maintenant j'essaie de traduire mes EAs en MQL5, mais je n'arrive même pas à saisir les bases du nouveau langage. Si vous le pouvez, envoyez-moi un programme simple pour ouvrir une position au croisement d'un indicateur de mouvement rapide et d'un indicateur de mouvement lent avec réglage du Stop et du Profit. Voici un exemple de programme qui fonctionne dans MQL4 :

#define Lot 0.1

extern int Magic = 105 ;

extern int St=70 ;

extern int Pr=50 ;

static int prevtime = 0 ;

extern int PerF=15 ;

extern int PerL=55 ;

int init() { return(0) ; } int deinit() { return(0) ; }

int start() {

si (Time[0] == prevtime) return(0) ;

prevtime = Time[0] ;

if( iMA(NULL,0,PerF,0,MODE_SMMA,PRICE_MEDIAN,1)>iMA(NULL,0,PerL,0,MODE_SMMA,PRICE_MEDIAN,1)

&& iMA(NULL,0,PerF,0,MODE_SMMA,PRICE_MEDIAN,2)<iMA(NULL,0,PerL,0,MODE_SMMA,PRICE_MEDIAN,2) )

{ OrderSend(Symbol(),OP_BUY,Lot,Ask,3,Ask-St*Point,Ask+Pr*Point, "2014",Magic,0,Green);}

return(0) ; }

Je ne peux pas le réécrire de MQL4 à MQL5 car je ne peux pas saisir la logique de MQL5.
 
Reshetov:
Installez Internet Explorer version 8 ou supérieure, même si vous ne l'utilisez jamais. Les développeurs ont-ils lié le Marché dans le terminal à ce navigateur pour une raison quelconque ?
MERCI ! !! ça marche !
 
il existe sur le marché différents scalper-advisors qui montrent des résultats étonnants dans le testeur. Mais fonctionneront-ils sur un compte réel?
 
if(OrderSelect(tik)==true)
        {
         if(ORDER_TYPE_BUY)
           {
            if(Bid-ORDER_PRICE_OPEN>_Point *(TrailingStop/10))
              {
               if(ORDER_SL<Bid-_Point*(TrailingStop/10))
                 {
                  bool Ans=trade.OrderModify(tik,ORDER_PRICE_OPEN,NormalizeDouble(Bid-_Point*(TrailingStop/10),5),ORDER_TP,ORDER_TIME_GTC,ORDER_TIME_EXPIRATION);
                  if(Ans==true)
                    {
                     Alert("Цена Stop Loss ордера успешно модифицирована.");
                     return;
                    }
                 }
              }
           }return;
Заходя в первое условие перескакивает на return, хотя переменная tik определена и является глобальной. Подозреваю что неправильно получаю данные выбранного ордера, есть идеи в чем косяк?
 
romadd:
Il y a plusieurs scalper EA sur le marché qui montrent des résultats étonnants dans le testeur. Mais fonctionneront-ils sur un compte réel?

Cela ne peut être testé sur un compte réel que si une version gratuite de l'EA est disponible. De nombreux vendeurs mettent en ligne des versions gratuites de leurs EA payants, afin qu'ils puissent être testés non seulement dans le testeur.

Mais il est conseillé, avant de tester sur le compte réel, de s'assurer que l'on n'a pas affaire au graal des testeurs sur les comptes de démonstration. Sinon, vous n'aurez pas de chance.

 

StrangerNet:


Заходя в первое условие перескакивает на return, хотя переменная tik определена и является глобальной. Подозреваю что неправильно получаю данные выбранного ордера, есть идеи в чем косяк?

Comptez les parenthèses pour l'appariement. J'ai compté plus d'ouvert que de fermé.
 
Reshetov:
Comptez les parenthèses pour voir si elles sont appariées. J'en ai compté plus d'ouverts que de fermés.

La condition supplémentaire est simple, elle reproduit ce que j'ai écrit pour le type d'ordre Vendre.

La question reste posée. Pourquoi ne va-t-elle pas plus loin que la première condition ?

if(OrderSelect(tik)==true)
        {
         if(ORDER_TYPE_BUY)
         //if(OrderGetInteger(ORDER_TYPE_BUY)==true)
           {
            if(Bid-ORDER_PRICE_OPEN>_Point *(TrailingStop/10))
              {
               if(ORDER_SL<Bid-_Point*(TrailingStop/10))
                 {
                  bool Ans=trade.OrderModify(tik,ORDER_PRICE_OPEN,NormalizeDouble(Bid-_Point*(TrailingStop/10),5),ORDER_TP,ORDER_TIME_GTC,ORDER_TIME_EXPIRATION);
                  if(Ans==true)
                    {
                     Alert("Цена Stop Loss ордера успешно модифицирована.");
                     return;
                    }
                 }
              }
           }

         else
           {
            if(Bid-ORDER_PRICE_OPEN<_Point *-1*(TrailingStop/10))
              {
               if(ORDER_SL>Bid-_Point*(TrailingStop/10))
                 {
                  bool Ans=trade.OrderModify(tik,ORDER_PRICE_OPEN,NormalizeDouble(Bid-_Point*(TrailingStop/10),5),ORDER_TP,ORDER_TIME_GTC,ORDER_TIME_EXPIRATION);
                  if(Ans==true)
                    {
                     Alert("Цена Stop Loss ордера успешно модифицирована.");
                     return;
                    }
                 }
              }
           }
        }
 
StrangerNet:

La condition est simple ici, elle duplique ce que j'ai écrit pour le type d'ordre Sell.

La question demeure ! Pourquoi ne va-t-il pas plus loin que la première condition ?

Attachez le code entier ou initialisez vos variables avant l'extrait de code, s'il vous plaît. Vous ne savez pas ce que vous avez dans vos variables, par exemple en

TrailingStop
Raison: