Особенности языка mql5, тонкости и приёмы работы - страница 51

Stanislav Korotky
31316
Stanislav Korotky  
fxsaber:

Хороший прием. Вся фишка в применении шаблона к TParent. Не встречал раньше подобного.

Ну это ж не множественное наследование. Это фактически цепочка Base -> A -> B -> C -> X. Кто мешает использовать её напрямую, если этого достаточно?

fxsaber
14390
fxsaber  
Stanislav Korotky:

Ну это ж не множественное наследование. Это фактически цепочка Base -> A -> B -> C -> X. Кто мешает использовать её напрямую, если этого достаточно?

Лаконичность.

Stanislav Korotky
31316
Stanislav Korotky  
fxsaber:

Лаконичность.

Тут не могу согласиться. ИМХО, напрямую прописать четыре класса наследника было бы короче и понятнее.

fxsaber
14390
fxsaber  
Stanislav Korotky:

Тут не могу согласиться. ИМХО, напрямую прописать четыре класса наследника было бы короче и понятнее.

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

class X : public INHERIT3(A, B, C)  {  };   // Объявляем класс, наследуемый от A, B, C
Stanislav Korotky
31316
Stanislav Korotky  
fxsaber:

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

Жалко на форуме помимо опросов нет еще и формы для ставок - вроде опроса с вариантами, но блокирующий несколько "копеек" на счете за ответ. Те, кто выберет правильный вариант, после наступления события получили бы ставки проигравших ;-). Я считаю, что не введут.

Alexey Navoykov
4463
Alexey Navoykov  
Stanislav Korotky:

Ну это ж не множественное наследование. Это фактически цепочка Base -> A -> B -> C -> X. Кто мешает использовать её напрямую, если этого достаточно?

Да, но тут вся вся особенность в том, что все исходные классы задаются и используются в виде шаблонов. Поэтому эту цепочку можно задавать в любом порядке. И по сути принципиальной  разницы с множественным наследованием нет.  Как я уже написал, могут быть подводные камни с классами.  А вот с интерфейсами всё идентично.  Единственное что выглядеть это будет немного костыльно, но тут уж каждый сам решает, шашечки ему или ехать )
Alexey Navoykov
4463
Alexey Navoykov  

И вот ещё добавлю. Полноценную альтернативу множественному наследованию (причём с более гибкими возможностями) можно было бы реализовать через перегрузку оператора приведения.  Но MQ почему-то не добавляют эту возможность перегрузки, хотя я уже давно прошу их об этом.  Причём я даже конкретного ответа от них не слышал, просто игнорируют и всё.

fxsaber
14390
fxsaber  

Бывают такие ситуации

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2017.07.24 09:27

Советник откомпилирован под 1641, где реализована быстрая работа с торговой историей.

Возможно ли при оптимизации попасть на Агента билда 1596, где история работает ОЧЕНЬ медленно, и, соответственно, получить замедление оптимизации в разы?

Как более общий случай - оптимизация на Облаке иногда дает разные результаты не только по времени, но и по расчетам. Иногда можно слышать, что результат оптимизации не совпадает с одиночным прогоном.

Связано это может быть как раз с тем, что Агенты, участвующие в оптимизации, и локальный Агент, участвующий в одиночном прогоне, могут различаться по номеру билда.

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

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2017.07.17 23:08

В очередной раз ошибка HistorySelect  в тестере. В 1626, вроде, не было. В 1629 - есть.

#include <Trade\Trade.mqh>

void OnTick()
{
  static CTrade Trade;

  const datetime NowTime = TimeCurrent();
  
  if (Trade.Buy(1) && Trade.PositionClose(_Symbol) && HistorySelect(NowTime, NowTime))
  {
    Print(HistoryDealsTotal()); // 0 - это при том, что мы открыли и закрыли позицию в NowTime-время
      
    ExpertRemove();
  }
}

Соответственно, если ваш советник при оптимизации попадет на Агента b1626, то он может показать один результат, а при прогоне на локальном Агенте b1641 одиночного прогона - совсем другой.

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

Благо, разработчики предусмотрели отсекатель неподходящих Агентов - INIT_AGENT_NOT_SUITABLE.


Поэтому рекомендовал бы в OnInit для Облачных оптимизаций прописать проверку для соответствий TerminalInfoInteger(TERMINAL_BUILD) нужным для вас значений.

Узнать же список подходящих для Вас проверок практически невозможно, поэтому, скорее всего, надо прописывать такое

int OnInit( void )
{
  // Если Агент не совпадает с билдом компиляции, отказываемся от его услуг
  if (TerminalInfoInteger(TERMINAL_BUILD) != __MQLBUILD__)
    return(INIT_AGENT_NOT_SUITABLE);
//....

Но это так же плохое решение. Более гибкое - это при оптимизации передавать на Агентов номер своего билда.


В общем, будьте бдительны.


ЗЫ. Возможно формировать торговый отчет каждого прогона Агента и получать его сразу прямо во время Оптимизации. Это может помочь разобраться в дальнейшем, почему результат Облачного Агента отличается от локального при одиночном прогоне. Автоматическое формирование таких отчетов во время Оптимизации и одиночного прогона возможно получить с помощью этой библиотеки.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Renat Fatkhullin, 2017.07.25 08:26

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

Это делается не каждую версию, а в зависимости от важности внесенных изменений.
Report
Report
  • голосов: 12
  • 2017.07.19
  • fxsaber
  • www.mql5.com
Библиотека для MetaTrader 4/5, которая позволяет формировать отчеты по истории торгов.
fxsaber
14390
fxsaber  

При отладке (не обязательно дебаг), когда нужно быстро в тестере уменьшить интервал тестирования, использую такие функции

// Выгружает эксперт, если количество сделок в истории больше DealsNum.
void ConditionStopExpert( const int DealsNum = INT_MAX )
{
  if ((DealsNum != INT_MAX) && ::HistorySelect(0, ::TimeCurrent()) && ::HistoryDealsTotal() > DealsNum)
    ::ExpertRemove();

  return;  
}

// Выгружает эксперт, если с момента запуска прошло AmountHours-часов.
void ConditionStopExpert( const double AmountHours )
{
  static datetime FirstTime = ::TimeCurrent();
  
  if (::TimeCurrent() > FirstTime + (datetime)(AmountHours * 3600))
    ::ExpertRemove();

  return;  
}
Alexey Navoykov
4463
Alexey Navoykov  
fxsaber:

При отладке (не обязательно дебаг), когда нужно быстро в тестере уменьшить интервал тестирования, использую такие функции

Подправьте код, у вас там в первой функции цифра 5 вместо DealsNum.