Автоматическая валидация, МТ4

 

Всем привет!

Автоматическая валидация, МТ4, не видит значение технического индикатора Moving Average. В советнике есть обращение к индикатору:

double MediumMax = iMA(NULL,PERIOD_D1,20,0,MODE_SMA,PRICE_HIGH,0);

Советник корректно работает в тестере и на реальном счёте, но при загрузке в маркет, в этом месте выдаёт ошибку (значение индикатора 0). Видимо надо что-то добавить, чтобы получить значение  индикатора  при автоматической валидации.

Если Вы знаете как решить эту задачу, помогите пожалуйста.

Спасибо!

 

Добавте в Init

double MediumMax = 50.0;

а в самом советнике потом просто

MediumMax = iMA(NULL,PERIOD_D1,20,0,MODE_SMA,PRICE_HIGH,0);
 
Tatyana Kulyapina:

Всем привет!

Автоматическая валидация, МТ4, не видит значение технического индикатора Moving Average. В советнике есть обращение к индикатору:

Советник корректно работает в тестере и на реальном счёте, но при загрузке в маркет, в этом месте выдаёт ошибку (значение индикатора 0). Видимо надо что-то добавить, чтобы получить значение  индикатора  при автоматической валидации.

Если Вы знаете как решить эту задачу, помогите пожалуйста.

Спасибо!

да - бывает (Периоды отличные от текущего не генерируются) сам проверял - c PERIOD_CURRENT всё отлично, ставлю М15 и нифига
 
Volodymyr Zubov #:

Добавте в Init

а в самом советнике потом просто

Это не помогло.

Сделали проверку:

   double MediumMax = 0;
   int i = 0;
   for(i = 0; MediumMax == 0 || i <= 50; i++)
      {
      MediumMax = iMA(NULL,PERIOD_D1,20,0,MODE_SMA,PRICE_HIGH,0);
      Sleep(1000);
      }
   if(MediumMax != 0)
      {
      }

Итог тот же, программа добирается до OrderSend, но не принимает объём ордера. Мы решили попробовать без индикатора и вообще исключили блок расчета объёма ордера и задали фиксированный объём:

extern   double            FixLot                  = 0.01;
...
         Lot = NormalizeDouble(FixLot,NormalizeLot);
         Level = NormalizeDouble(MaxLevelOrder(),_Digits);
         ticket = OrderSend(_Symbol,OP_BUYSTOP,Lot,Level,Slippage,0,0,iComment,Magic,0,clrAqua);

Итог тот же, программа добирается до OrderSend, но не принимает объём ордера. 
Советник исправно работает в тестере стратегий и на реальном счёте, а валидатор выдаёт:

 

Состояние тестирования: Тестирование завершилось с ошибками

  • Количество ошибок21
  • Запущен2022.01.30 21:45:18
  • Завершено2022.01.30 21:56:45
  • ТипЭксперт

test on EURUSD,H1 log files size exceeded 2051 MB, test terminated

2020.04.01 00:01:01 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:01 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:01 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:01 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:01 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:01 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:01 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:01 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:01 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:01 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:01 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:01 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:02 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:02 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:02 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:02 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:02 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:02 PRADO__1 EURUSD,H1: OrderSend error 4051

2020.04.01 00:01:02 PRADO__1 EURUSD,H1: invalid lots amount for OrderSend function 2020.04.01 00:01:02 PRADO__1 EURUSD,H1: OrderSend error 4051

 
так у вас теперь ошибка - инвалид объём значит нет проверки на минимально допустимый лот + максимальный + разрешённый шаг изменения объёма, в общем всё по стандарту
 
Aleksey Semenov #:
так у вас теперь ошибка - инвалид объём значит нет проверки на минимально допустимый лот + максимальный + разрешённый шаг изменения объёма, в общем всё по стандарту

Есть проверки:

double CalcRisk()
   {
   RefreshRates();
   double StopLoss   = StopLossCoef/_Point*MediumRange();               // 111.33
   if(StopLoss <= SYMBOL_TRADE_STOPS_LEVEL) {StopLoss = SYMBOL_TRADE_STOPS_LEVEL*3;}
   double Free       = AccountBalance();                                // 300         Кол-во свободных средств
   double LV         = MarketInfo(_Symbol,MODE_TICKVALUE);              // 0.91911765  Стоимость 1 пункта
   double Min_Lot    = MarketInfo(_Symbol,MODE_MINLOT);                 // 0,01
   double Max_Lot    = MarketInfo(_Symbol,MODE_MAXLOT);                 // 200
   double Step       = MarketInfo(_Symbol,MODE_LOTSTEP);                // 0,01
   double Calcul     = Free*MaxRisk/100/(StopLoss*LV);
   double Calc       = NormalizeDouble(Calcul,NormalizeLot);            // (300*0,75/100)/(64*0,92)=0,038
   if(Calc<Min_Lot)  Calc=Min_Lot;
   if(Calc>Max_Lot)  Calc=Max_Lot;
   return(Calc);
   }
//+------------------------------------------------------------------+
double Lot1()                                                            // Выбор способа определения объёма лота
   {
   if(MaxRisk <= 0)  {MyLot = FixLot;}
   if(MaxRisk > 0)   {MyLot = CalcRisk();}
   return(MyLot);
   }
// Выставление ордера BUY STOP
   if(AccountFreeMarginCheck(_Symbol,OP_BUY,Lot1()) <= 0 || GetLastError()==134 || SYMBOL_TRADE_FREEZE_LEVEL*_Point >= MediumRange()*StopLossCoef || 
   Ask >= MaxLevelOrder() - SYMBOL_TRADE_STOPS_LEVEL*_Point) return;
      {
      if(TodayMaxLevel() <  MaxLevelOrder() && CountBuy() == 0 && CountBuyStop() == 0 &&
       Ask < MaxLevelOrder() - (BarMaxLevel() - BarMinLevel())*StopLossCoef*OpenOrderCoef)
         {
         Lot = NormalizeDouble(Lot1(),NormalizeLot);
         Level = NormalizeDouble(MaxLevelOrder(),_Digits);
         ticket = OrderSend(_Symbol,OP_BUYSTOP,Lot,Level,Slippage,0,0,iComment,Magic,0,clrAqua);
         if(ticket > 0)
            {
            Sleep(Milliseconds);
            SLR = Level - MediumRange()*StopLossCoef;                      // Вычисляем SL
            SL = NormalizeDouble(SLR,_Digits);                      
            TPR = Level+(BarMaxLevel() - BarMinLevel())*TakeProfitCoef;    // Вычисляем TP
            TP = NormalizeDouble(TPR,_Digits);                                     
            if(OrderSelect(ticket,SELECT_BY_TICKET))                       // Выбираем наш ордер по тикету
               {
               if(!OrderModify(ticket,OrderOpenPrice(),SL,TP,0))           // Если ордер не модифицируется (меняем SL и TP)
                  {
                  Sleep(Milliseconds);
                  res=OrderDelete(ticket);
                  Print(">>>>>>>>>>>>>>>>>>>>>>>>>STRATEGY 1. A new BUY STOP pending order failed to set a STOP LOSS. The order has been removed. Look at the error code. "
                   + DoubleToStr(GetLastError(),0));                    // то выводим сообщение в журнал
                  }
               }
            }
         if(ticket<0) 
            {
            Print(">>>>>>>>>>>>>>>>>>>>>>>>>STRATEGY 1. Failed to place a new BUY STOP pending order. Look at the error code. " + DoubleToStr(GetLastError(),0));  // Проверка открытия ордера BUY
            }
         }
      }
 

4051 довольно странно, не 131 а именно 4051

добавьте ещё учёт шага изменения лота на всякий случай что-то типо такого, вдруг поможет

lotsize = NormalizeDouble((MathRound(lotsize/lotstep))*lotstep,2);
 
Aleksey Semenov #:

4051 довольно странно, не 131 а именно 4051

добавьте ещё учёт шага изменения лота на всякий случай что-то типо такого, вдруг поможет

В советнике есть, в OnInit():

// Определим кол-во знаков после запятой для расчёта лота
   if(MarketInfo(_Symbol,MODE_LOTSTEP)==1)        {NormalizeLot=0;}
   if(MarketInfo(_Symbol,MODE_LOTSTEP)==0.1)      {NormalizeLot=1;}
   if(MarketInfo(_Symbol,MODE_LOTSTEP)==0.01)     {NormalizeLot=2;}
   if(MarketInfo(_Symbol,MODE_LOTSTEP)==0.001)    {NormalizeLot=3;}

потом это применяется при нормализации:

Lot = NormalizeDouble(Lot1(),NormalizeLot);
 
Tatyana Kulyapina #:

В советнике есть, в OnInit():

потом это применяется при нормализации:

вы не так поняли что это такое - шаг может быть и 0.25 и 0.5 нормалайз дабл тут не поможет - нужно как я предложил делать
 
У вас советник на таймере или по тикам ?
 
Volodymyr Zubov #:
У вас советник на таймере или по тикам ?

по тикам

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