Ошибки, баги, вопросы - страница 2708

 

Предлагаю добавить конкретики в автоматическую валидацию продуктов в маркете. Помимо общих ошибок, сообщаемых валидатором, настоятельно требуется контекст выполняемой проверки и логи. В частности, я не могу уже пару лет обновить один индикатор из-за ошибки "tester takes too long time". Первая версия была загружена еще при "человеческом" модерировании и нареканий не вызывала. Критерии автовалидатора для выдачи данной ошибки абсолютно неясны.

Вот такой конкретный вопрос: какое количество тиков за какое количество времени на каком аппаратном обеспечении должен обеспечивать продукт, чтобы не возникало "tester takes too long time"?

Индикатор предназначен для обработки тиков алгоритмом MapReduce, используются целочисленные вычисления, так что ужимать там нечего, если только не выбросить сам алгоритм. Профайлер использовался, был добавлен троттлинг, чтобы пересчитывать массив новых тиков с заданным периодом. Безрезультатно.

На моем компе год тестируется за несколько минут. Что на самом деле происходит в автовалидаторе и почему он тормозит, невозможно в данный момент узнать.

Отсутствие нормальной поддержки продуктов - это проблема как для пользователей, так и для MQ - она сказывается на реализации.

 

Разве так должно быть?

class cA
  {
public:
   int               Add(int i1,int i2)
     {
      return i1+i2;
     };
                     cA()
     {
      Print("+++");
     };
                    ~cA()
     {
      Print("---");
     };
  };

void OnStart()
  {
   cA a=cA();
  }

Лог:

2020.04.17 18:39:32.996 test3 (EURUSD,M1)       +++
2020.04.17 18:39:32.996 test3 (EURUSD,M1)       +++
2020.04.17 18:39:32.996 test3 (EURUSD,M1)       ---
2020.04.17 18:39:32.996 test3 (EURUSD,M1)       ---

Двойной вызов конструктора и деструктора, как будто два объекта создаётся и удаляется. При использовании new и delete всё хорошо.

Билд 2380.

 
Aliaksandr Hryshyn:

как будто два объекта создаётся и удаляется.

Так и есть.

 
fxsaber:

Так и есть.

А мой объект создаётся вторым:

class cA
  {
public:
   int               my_i;
   int               Add(int i1,int i2)
     {
      return i1+i2;
     };
                     cA()
     {
      static int i=0;
      my_i=i;
      i++;
      Print("+++");
     };
                    ~cA()
     {
      Print("---");
     };
  };

void OnStart()
  {
   cA a=cA();
   Print(a.my_i);
  }
2020.04.17 18:47:34.771 test3 (EURUSD,M1)       +++
2020.04.17 18:47:34.771 test3 (EURUSD,M1)       +++
2020.04.17 18:47:34.771 test3 (EURUSD,M1)       ---
2020.04.17 18:47:34.771 test3 (EURUSD,M1)       1
2020.04.17 18:47:34.771 test3 (EURUSD,M1)       ---
 
Aliaksandr Hryshyn:

А мой объект создаётся вторым:

Первый объект.

cA a=cA();


Второй объект.

cA a=cA();
 

Тогда так надо:

cA a;
Print(a.my_i);
 
Stanislav Korotky:

На моем компе год тестируется за несколько минут. Что на самом деле происходит в автовалидаторе и почему он тормозит, невозможно в данный момент узнать.

Год за несколько минут — это много. Вряд ли кто-то дождался бы (если бы это был советник).
А визуально нормально рисуется? Можно что-то понять, наблюдая за тестером?

Добавьте заглушку для маркета — ускорение расчетов в ущерб точности (если это возможно), или вообще рисование "чего-то похожего". Продукт явно специфический, и тот, кому он нужен, сможет переключить нужный параметр.

 
Andrey Khatimlianskii:

Год за несколько минут — это много. Вряд ли кто-то дождался бы (если бы это был советник).
А визуально нормально рисуется? Можно что-то понять, наблюдая за тестером?

Добавьте заглушку для маркета — ускорение расчетов в ущерб точности (если это возможно), или вообще рисование "чего-то похожего". Продукт явно специфический, и тот, кому он нужен, сможет переключить нужный параметр.

По-моему, год за несколько минут в потиковом режиме, это нормально. Раньше на чемпионатах было ограничение минут 15-20 (точно не помню). Заглушка уже добавлена (троттлинг по времени). Можно пропускать тики, но тогда пропадает смысл продукта. Специфичность - понятие относительное: я знаю, что многие работают в потиковом режиме (и довесок с проверкой цен и/или объемов у всех есть). И тем более важно, иметь более точные критерии, плюс фидбэк от автовалидатора (если мы на форуме говорим "ваш терминал не работает", у нас MQ что спрашивают? - давайте логи и условия для воспроизведения; а тут получается, что нам сообщают, что мол наш продукт не работает, а конкретики нет). И более правильно - учитывать специфику продукта. Ведь общее время выполнения продукта - это не только время MQL-кода, но и самого терминала. Есть более дорогостоящие вызовы, такие как CopyTicksRange. Эти накладные расходы учитываются сейчас как недоработки MQL-продукта.

PS. В случае индикаторов более критичным, судя по всему, выходит не работа по тикам, а количество буферов (их много из-за особенностей задачи). Попробую для тестера ограничивать их число (это усложняет продукт и чревато ошибками, как и прочие навязываемые внешними условиями флаги, вроде троттлинга). Это еще раз доказывает необходимость в автовалидаторе варьировать оценку производительности по нескольким параметрам.

PPS. Я запрашиваю тики за последний день, а тестер их подгружает за 2 года - и на это тоже уходит время.

 
Stanislav Korotky:

PPS. Я запрашиваю тики за последний день, а тестер их подгружает за 2 года

Почему-то такое поведение официальное.

Наверное, можно было бы не генерировать бары совсем для советников, которые не использую индикаторы, не обращаются к барам и т.д.

Например, если есть только SymbolInfoTick - не генерировать бары, не хранить для copyticks историю.


Совсем не ясна эта баро-филия для серьезного алготрейдерского инструмента, как Тестер. Но поскольку даже эстеты МО продолжают жрать этот кактус, то, наверное, понимания не будет.

 

Почему в MQL нельзя вызывать защищенный конструктор из своего метода-фабрики?

class A1
{
  protected:
    A1(const bool x = false){}
  public:  
    static A1 *creator()
    {
      return new A1(true);
    }
};

void OnStart()
{
  A1 *a = A1::creator();
}

Код дает ошибку компиляции "'A1::A1' - cannot access protected member function", причем указывает строку, где начинается описание класса, а не там, где вызывается конструктор (то есть, нужно вручную искать, где проблема).

Но суть в том, что ошибки вообще не должно быть. C++ компилирует без проблем.