Программирование на MQL II. Как найти ошибку ?
|

Программирование на MQL II. Как найти ошибку ?

   Вот уже на протяжении нескольких месяцев журнал Forex Magazine публикует материал по программированию на языке MQL II, встроенном в торговый терминал MetaTrader, и многие из вас уже бесспорно овладели достаточными знаниями для написания своего кода.


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


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


   Дело тут не в том, что у начавшего программировать не хватает определённых знаний в предметной области, более того далее предполагается, что все необходимые знания и навыки уже получены из предыдущих выпусков Forex Magazine либо из каких-нибудь других источников. Основным источником проблем такого рода является невнимательность, спешка, неверное представление о работе той или иной функции языка и прочие причины, которые вкупе можно назвать “человеческим фактором”.


   Итак, перейдём к практике – рассмотрим пример приведённый в опубликованной в 8-ом номере журнала Forex Magazine статье “Программирование на MQL II: Медианное сглаживание”.


var: shift(0);
array: values[5](0);
var: ix(0), iy(0);
var: is_sorted(true);
 
SetLoopCount(0);
 
for shift = 0 to bars-5 {
  // помещаем значения из массива Open
   // во временный массив, с которым мы и будем
   // дальше работать
   for ix = 0 to 4 {
     values [ix] = O[shift + ix];
   }
   // сортируем массив методом пузырька
    for ix = 0 to 4 {
        is_sorted = true;
        for iy = 0 to 3 {
            var: tmp(0);
           if(values[iy] > values[iy+1]) then {
              tmp = values[iy];
              values[iy] = values[iy+1];
              values[iy+1] = tmp;
              is_sorted = false;
          };
      };
      if(is_sorted) then {
          break;
      };
  };
  SetIndexValue(shift, values [2]);
};


   Приведённый код должен нарисовать график, изображённый синим цветом на рисунке 1:



   Но, предположим, что во время набора программы мы случайно по тем или иным причинам допустили ошибку, и вместо цикла в строках 12-14, использовали цикл с неправильными присвоением значений сортируемого массива:


   for ix = 0 to 4 {
   values [ix] = O[shift];
   }


   Здесь мы ошиблись или просто забыли, что вместо O[shift] нужно использовать O[shift+ix], и в результате получили совсем не тот график. На рисунке 2 синим цветом начерчен правильный график, а красная кривая – график неправильно написанного индикатора:



   Подумать только – такая малость может перечеркнуть часы труда и раздумий! И я уверяю вас, что найти такую ошибку будет не так-то просто путём обычного разглядывания кода.


   Каким же образом можно обнаружить ошибку? Самым простым способом было бы вывести на экран информацию о заполненном массиве для анализа. К счастью разработчики MetaTrader’a добавили такую возможность в MQL II и в саму программу.


   После заполнения массива в цикле мы можем вывести его в окно Journal программы MetaTrader. Достаточно в код программы добавить инструкцию print() с нужными параметрами.


   Добавим следующую строку после выше рассмотренного цикла заполнения массива:


   print (values[0] + ” ” + values[1] + ” ” + values[2] + ” ” + values[3] + ” ” + values[4]);


   Команда print() говорит MetaTrader’у, что в окно журнала нужно вывести её параметры – то есть то, что заключено в круглые скобки, следующие за ней. На рисунке 3 показано, что каждое выполнение главного цикла программы вызывает вывод в журнал строки со значениями массива values.



   В частности, вторая строчка сверху говорит нам о том, что 2004.04.24 эксперт median2 послал в окно журнала следующее сообщение: “1.2545 1.2545 1.2545 1.2545 1.2545”. Это, как мы понимаем, значения, соответственно, первого, второго, третьего и так далее элементов массива values. Тот факт, что значения всех элементов массива values одинаковы, хотя, судя по графику котировок, они должны были бы быть различны, должен нас насторожить.


   Проанализировав это, мы можем понять, что в коде присутствует ошибка, и она допущена выше той строчки, в которой стоит команда print(). Вот теперь-то нам придется как следует взглянуть на локализованный участок кода, в котором потенциально присутствует ошибка и исправить его. Правильный код напечатает в журнал текст приведённый на рисунке 4 – на этот раз в массив заносятся правильные значения.



   У этого способа отладки много возможностей, так как команда print() может печатать как числа, так и строки и даже дату и время. Так каждый раз, когда вы не до конца уверены в правильности своих действий можно вывести определённые значения в журнал и затем в ручную удостовериться в их правильности.


   Однако всегда следует помнить – каждая лишняя команда немного замедляет работу программы.


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


   В таких случаях может помочь условный оператор if(). Если завести переменную


   var: debug(false);


   и потом каждый отладочный вызов print() поместить в тело условного оператора if, то, просто меняя значения переменной debug, можно включать или выключать исполнение этой инструкции из кода.


   Например, в следующем случае отладочная информация из-за того, что переменная debug при создании инициализируется значением false (ложь), не будет выводиться на экран:


for ix = 0 to 4 {
values [ix] = O[shift+ix];
}
if(debug) then {
print(values[0]+” “+values[1]+” “+values[2]+”
“+values[3]+” “+values[4]);
}


   И наоборот, достаточно переменной debug при создании задать значение true, то есть написать var: debug(true); то отладочная информация будет выведена в журнал.


   На этом мы закончим рассказ об отладке ваших программ с помощью команды print() и терминального окна Journal. Но, стоить заметить, что это ещё не все способы отладки и в следующем номере мы рассмотрим использование других возможностей отладки программ на языке MQL II исполняемых в MetaTrader’е.


Александр Иванов
для Forex Magazine