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

 
fxsaber #:

Чтобы конструктивно обсуждать, нужно пример непонятного привести. Вот выше применил.


Мне нужно было перебрать комбинации входных параметров ТС для Тестера. И для каждой комбинации запустить оптимизацию.

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

Конструктивно я не могу обсуждать Ваш код - слишком затратно для моего мозга понять его.

Просто интересно, это фишка такая, стиль, любовь, или демонстративный признак крутизны. Кажется, никто так активно больше не использует макросы.

Я не критикую, просто интересно... Вам всегда легко читать чужой код?

fxsaber #:

Соответственно, сделал через макрос. Чтобы удобно (одной строкой) задавать изменение одного из параметров ТС в наборе.


Вроде, оптимально получилось.  Ведь другими инструментами лучше не решить задачу.

Ну не знаю, я бы делал внешнее изменение через настройки или файл... т.е. сама идея, что для изменения настроек требуется перекомпиляция несколько странная для меня.

 
Aleksey Vyazmikin #:

Просто интересно, это фишка такая, стиль, любовь, или демонстративный признак крутизны. Кажется, никто так активно больше не использует макросы.

Это просто решение поставленной задачи. Если через макросы лучше - делаю через макросы. Возможно, задачи ставлю немного нестандартные, поэтому и решения такие выходят.

Я не критикую, просто интересно... Вам всегда легко читать чужой код?

Редко читаю чужой код. Очень редко. Например, Generic-библиотеку не понимаю, но использую. CTrade - очень легко. В обоих случаях авторы - MQ.

Ну не знаю, я бы делал внешнее изменение через настройки или файл... т.е. сама идея, что для изменения настроек требуется перекомпиляция несколько странная для меня.


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

Вот так работает.

#define MACROS(T, A, B, C, D)                                                                          \
  for (T A = (B); (T)NormalizeDouble(A, 8) <= (T)NormalizeDouble(C, 8); A += D)                        \
  {                                                                                                    \
    string Str = ((Amount == 1) ? NULL : (Str + ", ")) + #A + " = " + (string)(T)DoubleToString(A, 1); \
    int Amount = Amount * (int)((C - (B)) / (D) + 1.1);                                                \
                                                                                                       \
    MTTESTER::SetValue(Settings, #A, (string)(T)DoubleToString(A, 1));
    
MACROS(int, inAmountDeleteIntervals, 15, 15, 5)
  MACROS(int, inBestIntervalOnTester, 0, 3, 1)
    MACROS(double, inMinPF, 2.0, 2.8, 0.4)
      MACROS(double, inIntervalMinPF, 1.8, 2.2, 0.4)
        MACROS(int, inIntervalMinTotal, 200, 200, 200)
          MACROS(int, inAttenuationPerHour, 0, 100, 50)
            Print((string)++Count + " / " + (string)Amount + ": " + Str);
                                        
            Run(Settings);                                                
          }
        }
      }
    }
  }                               
}

У меня OnTester зависит от множества параметров (подсвечены). Добавить новый параметр в перебор - одна строка.


Задача нестандартная. Поэтому и решение такое. Как видно, удобное.

 
fxsaber #:

Это просто решение поставленной задачи. Если через макросы лучше - делаю через макросы. Возможно, задачи ставлю немного нестандартные, поэтому и решения такие выходят.

Получается, что специально не ищите вариант для использования макросов.

fxsaber #:

Задача нестандартная. Поэтому и решение такое. Как видно, удобное.

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

Помогли рассеять мысли, что Вам просто нравится использовать такие нестандартные решения.

 
Aleksey Vyazmikin #:

Получается, что специально не ищите вариант для использования макросов.

Когда во время решения вижу кучу повторов, автоматически задумываюсь, как сделать оптимальнее. Это могут быть функции, ООП, указатели на функции, шаблоны, макросы, ArraySwap и прочее.

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

Автоматизация Тестера в несколько строк простым скриптом. Т.е. время на его написание и дальнейшие правки в тысячи раз занимает меньше времени/сил, чем ручная рутина.

Помогли рассеять мысли, что Вам просто нравится использовать такие нестандартные решения.

Не люблю программирование. Приходится себя заставлять.

 
fxsaber #:
Не люблю программирование. Приходится себя заставлять.

А какой вид деятельности любим?

 
Aleksey Vyazmikin #:

А какой вид деятельности любим?

В силу очевидных причин он не ответит.
Но я наберусь борзости и отвечу за него. 
Сабер не программист. Программистов много. Разработчиков алгоритмов, или тех, кто обладает архитертурными навыками, работающих на более высоком уровне абстракции, совсем мало. Они любят изобретать, но не любят кодить, хотя умеют это делать иногда лучше профессиональных программистов. Программирование для них - лишь инструментарий. Они практически никогда не возьмутся за реализацию чужих идей, которые ниже уровня их идей. 
 
Nikolai Semko #:
В силу очевидных причин он не ответит.
Но я наберусь борзости и отвечу за него. 
Сабер не программист. Программистов много. Разработчиков алгоритмов, или тех, кто обладает архитертурными навыками, работающих на более высоком уровне абстракции, совсем мало. Они любят изобретать, но не любят кодить, хотя умеют это делать иногда лучше профессиональных программистов. Программирование для них - лишь инструментарий. Они практически никогда не возьмутся за реализацию чужих идей, которые ниже уровня их идей. 

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

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

 
Оффтоп
 

Если советник использует данные из файла, то есть несколько способов передать их Агентам.

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

Для этого включил семь локальных Агентов на мат. режим, песочницы которых находятся на RAMDrive.


Облако - tester_file.

#define FILENAME "Ticks.bin" // https://www.mql5.com/ru/forum/478178/page10#comment_55702486

#property tester_no_cache
#property tester_file FILENAME

input int inRange = 0;

double OnTester()
{
  MqlTick Ticks[];
  
  return(FileLoad(FILENAME, Ticks) ? ArraySize(Ticks) : -1);
}


Эффективность.

optimization finished, total passes 1000
optimization done in 0 minutes 30 seconds
shortest pass 0:00:00.078, longest pass 0:00:00.234, average pass 0:00:00.192
local 1000 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)


Локальные агенты - COMMON-file.

#define FILENAME "RamDriveFolder\\Ticks.bin" // https://www.mql5.com/ru/forum/478178/page10#comment_55702486

#property tester_no_cache

input int inRange = 0;

double OnTester()
{
  MqlTick Ticks[];
  
  return(FileLoad(FILENAME, Ticks, FILE_COMMON) ? ArraySize(Ticks) : -1);
}


Эффективность.

optimization finished, total passes 1000
optimization done in 0 minutes 27 seconds
shortest pass 0:00:00.143, longest pass 0:00:00.300, average pass 0:00:00.179
local 1000 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)


Локальные Агенты - #resource.

#resource "Ticks.bin" as MqlTick Ticks[] // https://www.mql5.com/ru/forum/478178/page10#comment_55702486

#property tester_no_cache

input int inRange = 0;

double OnTester()
{
  return(ArraySize(Ticks));
}


Эффективность.

optimization finished, total passes 1000
optimization done in 0 minutes 00 seconds
shortest pass 0:00:00.000, longest pass 0:00:00.000, average pass 0:00:00.000
local 1000 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)


Итог.

Эффективность.

tester_file COMMON-file #resource
30 seconds 27 seconds

0 seconds

Нужно быстро и без Облака - #resource самый эффективный способ передачи данных на Агенты.

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


Если нужно много данных, то совсем неоднозначно, что имеет смысл связываться с Облаком.


Результаты OnTester на всех вариантах совпали - 1368151. Кеш на всякий случай руками удалялся перед запуском.

 
fxsaber #:

Нужно быстро и без Облака - #resource самый эффективный способ передачи данных на Агенты.

К сожалению, помимо ограничения на размер (sizeof(#resource) < 128Mb) с новыми данными требуется перекомпиляция, т.к. они вшиваются в EX5.

Если нужно много данных, то совсем неоднозначно, что имеет смысл связываться с Облаком.

Ресурсы будут работать в Облаке из-за вшитости данных.