초보자의 질문 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 :

디버깅할 때 EA가 충돌하지만 이론상 Tik==0 조건이 false가 될 때까지 OnTick에서 순환해야 합니다.

실수를 찾으십시오. 컴파일할 때 오류 메시지 에 주의하십시오.

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

변수를 생성하려고 하고 있으며 그러한 변수가 이미 전역 선언에 존재한다고 말합니다.

글쎄, 등등. 등.

 
Harigal :

안녕하세요! 1년 전 나는 MQL4를 쉽게 마스터했고 지금은 Expert Advisors를 MQL5로 번역하려고 노력하고 있지만 새로운 언어의 기초조차 이해할 수 없습니다. 가능하다면 Stop 및 Profit을 설치하여 빠른 이동 평균과 느린 이동 평균의 교차점에서 거래를 시작하는 가장 간단한 프로그램을 다시 작성하십시오. 다음은 MQL4에서 작동하는 프로그램의 예입니다.

#로트 0.1 정의

외부 int 매직 = 105;

외부 정수 St = 70;

외부 int Pr=50;

정적 정수 이전 시간 = 0;

외부 정수 PerF=15;

외부 intPerL=55;

정수 초기화() { 반환(0); } int deinit() { 반환(0); }

정수 시작() {

if (시간[0] == 이전 시간) return(0);

이전 시간 = 시간[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);}

리턴(0); }

MQL5의 논리를 잡을 수 없기 때문에 MQL4에서 MQL5로 다시 쓸 수 없습니다.
 
Reshetov :
사용하지 않더라도 Internet Explorer 버전 8 이상을 설치하십시오. 어떤 이유로 개발자는이 브라우저에 터미널의 Market을 묶었습니까?
감사합니다 !! 벌었다
 
여기 시장에는 테스터에서 놀라운 결과를 보여주는 다양한 스캘퍼-EA가 있습니다. 그들은 실제 계정 에서 작동합니까?
 
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가 있습니다. 그들은 실제 계정 에서 작동합니까?

이는 어드바이저 무료 버전이 있는 경우에만 실제 계정에서 확인할 수 있습니다. 많은 판매자가 테스터에서만 테스트할 수 있도록 유료 어드바이저의 무료 버전을 제공합니다.

그러나 실생활에서 확인하기 전에 데모 계정에서 테스터 성배를 다루지 않는지 확인하는 것이 바람직합니다. 그렇지 않으면 운이 좋지 않을 것입니다.

 

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 :

거기에 더 나아가 조건은 간단하고 내가 판매 주문 유형 에 대해 작성한 것과 중복됩니다.

질문은 열려 있습니다! 첫 번째 조건을 벗어나지 않는 이유는 무엇입니까?

전체 코드를 첨부하거나 코드 조각 전에 변수를 초기화하십시오. 예를 들어 다음과 같이 변수에 무엇이 있는지 결코 알 수 없습니다.

TrailingStop
사유: