MQL4 및 MQL5에 대한 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 - 페이지 1781

 
MakarFX # :

차이점을 다시 한 번 강조합니다.

1 옵션

옵션 2

네. 감사하다. 이해했다.

 
Mihail Matkovskij # :

맹목적으로 OrdersTotal , OrdersHistoryTotal ,

주문선택

노력합니다. 감사합니다.

 
//+-----------------------------------------------------------------------------------------------+
//|                                                                     Simple Moving Average.mq4 |
//|                                                                                               |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Copyright 2021"
#property link        " https://www.mql5.com/ru/users/ "
#property version    "1.00"
#property strict

// Параметры советника
input string   sParametersEA = "" ;     // Параметры советника
input double   Lot           = 0.01 ;   // Количество лотов
input double   LotControl    = 0.01 ;   // Контрольная лотность
input int      StopLoss      = 30 ;     // Уровень убытка
input int      TakeProfit    = 30 ;     // Уровень прибыли
input int      Deviation     = 20 ;     // Отступ цены входа
input int      Slippage      = 3 ;       // Проскальзование (в пунктах)
input int      Magic         = 1 ;       // Индентификатор советника
input double   K_Martin1     = 2.0 ;     // Множитель мартин 1
input double   K_Martin2     = 2.0 ;     // Множитель мартин 2
input double   K_Martin3     = 2.0 ;     // Множитель мартин 3
input int      OrdersClose   = 5 ;       // Ограничение лотности мартин1
input int      OrdersClose2  = 5 ;       // Ограничение лотности мартин2
input int      DigitsLot     = 2 ;       // Точность лотности
// Параметры индикатора
input string   ParametersMA  = "" ;     // Параметры индикатора
input int      PeriodMA      = 14 ;     // Период мувинга
input int      MovingShift   = 1 ;       // Сдвиг мувинга
// Глобальные переменные
string AC;
datetime Start;
double dMA;
double MaxMartinLot;
double MaxMartinLot2;
double openPrice;   // цена открытия позиции
//+-----------------------------------------------------------------------------------------------+
int OnInit ()
  {
Start          = TimeCurrent ();
MaxMartinLot   = Lot* MathPow ( 1.4 ,OrdersClose);
MaxMartinLot2  = Lot* MathPow (K_Martin2,OrdersClose2);
AC             = StringConcatenate ( " " , AccountCurrency());
return ( INIT_SUCCEEDED );
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick ()
{
// Получим значение индикатора
   dMA = iMA ( Symbol (), 0 ,PeriodMA, MovingShift, MODE_SMA , PRICE_CLOSE , 0 ); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.
   
   if (GetLotSize()<LotControl)  openPrice = dMA;
   
     else 
    openPrice = dMA + Deviation * _Point ;
// Если нет открытых ордеров, то входим в условие
   if (CountOrders()== 0 )
   {

// Если появился сигнал на покупку, то откроем ордер на покупку
       if (bSignalBuy() == true )
         vOrderOpenBuy();

// Если появился сигнал на продажу, то откроем ордер на продажу
       if (bSignalSell() == true )
         vOrderOpenSell();
   }
}
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
int CountOrders() 
  {
   int cnt= 0 ;
   int i= OrdersTotal ()- 1 ;
   for ( int pos=i;pos>= 0 ;pos--)
     {
       if ( OrderSelect (pos, SELECT_BY_POS, MODE_TRADES))
        {
         if (OrderSymbol()== _Symbol )
           {
             if (OrderMagicNumber()==Magic) cnt++;
           }
        }
     }
   return (cnt);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if (openPrice > Open[ 1 ] && openPrice < Close[ 1 ]) //Open[1] и Close[1]- цены открытия и закрытия каждого бара текущего графика.
   
   return ( true );
   
   return ( false );
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
   
  {
   if (openPrice< Open[ 1 ] && openPrice > Close[ 1 ])

   return ( true );

   return ( false );
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
// Тикет ордера
   int iOTi = 0 ;   

   iOTi = OrderSend ( Symbol (), OP_BUY, LOT(), Ask, Slippage, 0 , 0 , "" , Magic, 0 , clrNONE );
   
// Проверим открылся ли ордер
   if (iOTi > 0 )
// Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
// Если нет, то получим ошибку
      vError( GetLastError ());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
// Тикет ордера  
   int iOTi = 0 ;   
//Print(bCheckOrders());
   iOTi = OrderSend ( Symbol (), OP_SELL, LOT(), Bid, Slippage, 0 , 0 , "" , Magic, 0 , clrNONE );

// Проверим открылся ли ордер
   if (iOTi > 0 )
// Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
// Если нет, то получим ошибку
      vError( GetLastError ());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify( int iOTi)
  {
   int     iOTy = - 1 ;     // Тип ордера
   double dOOP = 0 ;     // Цена открытия ордера
   double dOSL = 0 ;     // Стоп Лосс
   int     iMag = 0 ;     // Идентификатор советника
   double dSL  = 0 ;     // Уровень убытка
   double dTP  = 0 ;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if ( OrderSelect (iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if (OrderSymbol() == Symbol () && OrderMagicNumber() == iMag)
     {
// Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
       if (dOSL == 0 )
        {
         if (iOTy == OP_BUY)
           {
            dSL = NormalizeDouble (dOOP - StopLoss * Point , Digits );
            dTP = NormalizeDouble (dOOP + TakeProfit * Point , Digits );

             bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0 , clrNONE );
           }             
         if (iOTy == OP_SELL)
           {
            dSL = NormalizeDouble (dOOP + StopLoss * Point , Digits );
            dTP = NormalizeDouble (dOOP - TakeProfit * Point , Digits );

             bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0 , clrNONE );
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError( int iErr)
  {
   switch (iErr)
     {
       case 129 :   // Неправильная цена
       case 135 :   // Цена изменилась
       case 136 :   // Нет цен
       case 138 :   // Новые цены
         Sleep ( 1000 );
         RefreshRates();
         break ;

       case 137 :   // Брокер занят
       case 146 :   // Подсистема торговли занята
         Sleep ( 3000 );
         RefreshRates();
         break ;
     }
  }
//+-----------------------------------------------------------------------------------------------+
double LOT()
{
   int n= 0 ;
   int m= 0 ;
   int v= 0 ;
   double OL=Lot;
   for ( int j = OrdersHistoryTotal()- 1 ; j >= 0 ; j--)
   {
       if ( OrderSelect (j, SELECT_BY_POS,MODE_HISTORY))
      {
         if (OrderSymbol() == Symbol () && OrderMagicNumber() == Magic)
         {
             if (OrderProfit()> 0 ) 
            {

               if (n== 0 ) OL= NormalizeDouble (OrderLots()+K_Martin1,DigitsLot);
               n++;
               
               if ((OL>=MaxMartinLot)&& (m== 0 )) OL= NormalizeDouble (OrderLots()*K_Martin2,DigitsLot);
               m++;
               
               if ((OL>=MaxMartinLot2) && (v== 0 )) OL= NormalizeDouble (OrderLots()*K_Martin3,DigitsLot);
               v++;
            }
             else
            {
               if (n== 0 ) { return (Lot);}
               else { return (OL);}
            }
         }
      }
   }  
   return (OL);
}
//+------------------------------------------------------------------+
//|  Функция считает по символу и магику                             |
//|  размер лота с начала цикла                                      |
//+------------------------------------------------------------------+
double GetLotSize()
  {
   double Ls= 0 ;
   datetime t= 0 ;
   int i=OrdersHistoryTotal();
   for ( int pos= 0 ; pos<i; pos++)
     {
       if ( OrderSelect (pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if (OrderSymbol()== _Symbol && OrderMagicNumber()==Magic)
           {
             if (OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if (t<OrderCloseTime()) {t=OrderCloseTime(); Ls=OrderLots();}
              }
           }
        }
     }
   return Ls;
  }

void OnTick() 부분을 수정했습니다.

특정 로트 크기(LotControl)에 도달하면 지정된 수의 포인트가 신호(편차 매개변수)에 추가됩니다.

결국 문제와 함께 작동합니다.

첫째, 백 테스팅은 500 거래 (분당 1-2 거래) 후에 거의 중단되었습니다.

(정상 속도로 시작한 다음 점점 더 느려짐)

둘째, 편차는 (LotControl) 이후가 아니라 지정된 로트 크기 이후 1~2단계 후에 연결됩니다.

 
законопослушный гражданин # :

void OnTick() 부분을 수정했습니다.

특정 로트 크기(LotControl)에 도달하면 지정된 수의 포인트가 신호(편차 매개변수)에 추가됩니다.

결국 문제와 함께 작동합니다.

첫째, 백 테스팅은 500 거래 (분당 1-2 거래) 후에 거의 중단되었습니다.

(정상 속도로 시작하여 점점 더 느려짐)

둘째, 편차는 (LotControl) 이후가 아니라 지정된 로트 크기 이후 1~2단계 후에 연결됩니다.

다음과 같이 시도하십시오.

무효 OnTick()에서 제거

 // Получим значение индикатора
   dMA = iMA ( Symbol (), 0 ,PeriodMA, MovingShift, MODE_SMA , PRICE_CLOSE , 0 ); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.
   
   if (GetLotSize()<LotControl)  openPrice = dMA;
   
     else 
    openPrice = dMA + Deviation * _Point ;

그리고 여기에 넣어

 //+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   dMA = iMA ( Symbol (), 0 ,PeriodMA, MovingShift, MODE_SMA , PRICE_CLOSE , 0 );
   openPrice = dMA + Deviation * _Point ;
   if (GetLotSize()<LotControl) openPrice = dMA;
   if (openPrice > Open[ 1 ] && openPrice < Close[ 1 ]) //Open[1] и Close[1]- цены открытия и закрытия каждого бара текущего графика.
   
   return ( true );
   
   return ( false );
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   dMA = iMA ( Symbol (), 0 ,PeriodMA, MovingShift, MODE_SMA , PRICE_CLOSE , 0 );
   openPrice = dMA + Deviation * _Point ;
   if (GetLotSize()<LotControl) openPrice = dMA;
   if (openPrice< Open[ 1 ] && openPrice > Close[ 1 ])

   return ( true );

   return ( false );
  }
 
MakarFX # :

다음과 같이 시도하십시오.

무효 OnTick()에서 제거

그리고 여기에 넣어

비슷한 결과.

신호에 관한 것이 아닙니다. 비슷한 조언자가 두 명 더 있는데 브레이크가 없습니다.

 
MakarFX # :

다음과 같이 시도하십시오.

무효 OnTick()에서 제거

그리고 여기에 넣어

먼저 이 일에 죄를 지었습니다.

 double GetLotSize()
  {
   double Ls= 0 ;
   datetime t= 0 ;
   int i=OrdersHistoryTotal();
   for ( int pos= 0 ; pos<i; pos++)
     {
       if ( OrderSelect (pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if (OrderSymbol()== _Symbol && OrderMagicNumber()==Magic)
           {
             if (OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if (t<OrderCloseTime()) {t=OrderCloseTime(); Ls=OrderLots();}
              }
           }
        }
     }
   return Ls;
  }

그러나 다른 두 올빼미는 테스터에서 그녀와 잘 작동합니다.

 
законопослушный гражданин # :

먼저 이 일에 죄를 지었습니다.

이 문제로 모든 것이 좋습니다.

나중에 코드를 살펴보고 테스터에서 사용하는 시간대와 쌍을 작성하겠습니다. 브레이크가 있는지 확인하겠습니다.

 
MakarFX # :

이 문제로 모든 것이 좋습니다.

나중에 코드를 살펴보고 테스터에서 사용하는 시간대와 쌍을 작성하겠습니다. 브레이크가 있는지 확인하겠습니다.

예, 어떤 쌍.

저는 AUD/USD M15를 사용합니다.

귀하의 표시기와 동일한 문제가 있었습니다(첨부됨)

거기에서 나는 제거 방법으로 이것이 프로세스를 늦추고 있음을 발견했습니다.

 double GetProfitFromStart()
  {
   double lp= 0 ,cp= 0 ;
    for ( int i= 0 ; i<OrdersHistoryTotal(); i++)
     {
       if ( OrderSelect (i, SELECT_BY_POS, MODE_HISTORY))
        {
         if (OrderSymbol()== _Symbol && OrderMagicNumber()==Magic)
           {
             if (OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if (Start<OrderCloseTime()) {lp+=OrderProfit()+OrderCommission()+OrderSwap();}
              }
           }
        }
     }
   for ( int pos= OrdersTotal ()- 1 ;pos>= 0 ;pos--)
     {
       if ( OrderSelect (pos, SELECT_BY_POS, MODE_TRADES))
        {
         if (OrderSymbol()== _Symbol && OrderMagicNumber()==Magic)
           {
             if (OrderType()==OP_BUY || OrderType()==OP_SELL) {cp=OrderProfit()+OrderCommission()+OrderSwap();}
           }
        }
     }
   return (lp+cp);
  }
파일:
 
законопослушный гражданин # :

예, 어떤 쌍.

저는 AUD/USD M15를 사용합니다.

귀하의 표시기와 동일한 문제가 있었습니다(첨부됨)

거기에서 나는 제거 방법으로 이것이 프로세스를 늦추고 있음을 발견했습니다.

변경 주문 피킹

 for ( int i= OrdersHistoryTotal()- 1 ; i>= 0 ; i--)
 
MakarFX # :

변경 주문 피킹

여러분, 누가 뭐라고 해도 마지막 검사에서 주기 지수의 값을 기억하지 못한다면 주기는 전체 기록을 통해 실행됩니다. 그리고 많을수록 주기가 길어집니다.