初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 200

 

デバッグ中、EAはクラッシュしますが、理論的にはTik==0条件がfalseになるまでOnTIckで循環する必要があります。

 //+------------------------------------------------------------------+
//|                                                         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:

デバッグの際、Expert Advisorはクラッシュしますが、アイデアとしては、条件Tik=0が偽になるまでOnTIckのループを実行する必要があります。

エラーを探す。コンパイルするときは、エラーメッセージに 注意してください。

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

は、変数を作成しようとしていて、その変数がすでにグローバル宣言に存在していると言っています。

などなど。

 
Harigal:

こんにちは!1年前にMQL4を簡単にマスターしました。 今、自分のEAをMQL5に翻訳しようとしているのですが、新しい言語の基本すら把握できていません。もし可能であれば、高速移動するインジケータと低速移動するインジケータのクロスでポジションを持ち、ストップとプロフィットを設定する簡単なプログラムを送ってください。ここでは、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() {

if (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);} { OrderSend(Symbol(,OP_BUY,Lot,Ask,3,Ask-St*Point,Ask+Pr*Point), "2014",Magic,0,Green)

return(0); }

MQL4からMQL5への書き換えは、MQL5のロジックがつかめないのでできない。
 
Reshetov:
Internet Explorerのバージョン8以上をインストールしてください(使用しない場合も含む)。開発者は、何らかの理由で端末のMarketをこのブラウザに結びつけたのでしょうか?
ありがとうございます。
 
この市場には、テスターで驚くべき結果を示す様々なスキャルパーアドバイザーがあります。しかし、実際のアカウントで 使えるのだろうか?
 
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:
市場には、テスターで素晴らしい結果を出している様々なスキャルパーEAがあります。しかし、実際のアカウントで 使えるのだろうか?

これは、EAの無料版が利用可能な場合にのみ、実際の口座でテストすることができます。多くの販売者が有料EAのFree版をアップしているので、テスターだけでなく、テストすることができます。

しかし、実際の口座でテストする前に、デモ口座のテスターグレイルを扱っていないことを確認することをお勧めします。そうでなければ、運が悪いとしか言いようがありません。

 

StrangerNet:


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

ペアリングのためのブラケットを数える。クローズドよりオープンを多く数えました。
 
Reshetov:
括弧を数えて、ペアになっているかどうかを確認します。クローズドよりオープンの方が多くカウントされています。

この条件は単純で、私が売り注文のタイプ について書いたものと重複しています。

という疑問は残ります。なぜ、最初の条件より先に進まないのか。

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:

そこでの条件は単純で、私がSellorder type 用に書いたものと重複しています。

疑問は残る!なぜ、最初の条件より先に進まないのでしょうか?

コード全体を添付するか、コードスニペットの前に変数を初期化するか、どちらかをお願いします。変数に何を入れているのか分かりませんが、例えば

TrailingStop
理由: