О стиле кодирования - страница 2

 

Здесь приходится выбирать одно из двух:

1) Удобство написания и легкая читаемость кода.

2) Скорость выполнения программы.

 

Лично я всегда отдавал предпочтение второму варианту, поэтому стараюсь все переменные объявлять на глобальном уровне и если возможно не использовать функции (давно заметил влияние этого на скорость вычислений). Здесь нужно понимать, что эксперт будет крутиться на компе сутками, иногда требуется проведение оптимизации и т.п. Поэтому скорость вычислений и низкая потребляемость ресурсов очень важна.

 

А теперь посмотрим со стороны на разные языки программирования. Например, Basic - легко кодить, легко читать код, но скорость вычисления... Теперь сравним с ним С++. Здесь уже поменялись полюса - кодить сложнее (читаемось кода ухудшилась), но скорость вычисления значительно возрасла. А если взять Ассемблер - код практически нечитаем...

 

Другое дело, что странно когда программа написанная на одном и том же языке также подпадает под эти критерии и нужно выбирать - либо читаемость кода, либо скорость выполнения программы (хотя здесь ничего странного нет, объявить переменную - затрата времени; обратиться к функции и передать ей параметры - затрата времени). Но это факт, который кстати замечен не только в mql4...

 

Я предпочитаю первое - возможно потому, что в MQL4 еще не сталкивался с такими случаями, когда мои вычисления настолько обширны, что приходится выбирать между читаемостью и скоростью. На тиках я не играю, так что какая-то сумасшедшая скорость вычислений мне точно не нужна.

С другой стороны, трудно представить себе такой советник, который не приходится потом модифицировать.

 
Mathemat >>:

На тиках я не играю

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

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

 

очень советую: http://astyle.sourceforge.net/ - форматер С-текстов, но отлично справляется с MQ4.

всего одна команда: AStyle.exe -b -t -p before.mq4 превращает "упакованый" текст в конфетку


 

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

 

В свое время задавался вопросом "Какой стиль программирования выбрать". Так как опыта было мало, то решил проблему просто - открыл исходники FreeBSD и внимательно посмотрел какой стиль используют Old School программисты. Тогда некоторые вещи мне казались неудобными, но сейчас я понимаю почему они выбрали имено такие решения.

Итак, вот правила по которым я пишу:

int main()

{

   int sum;

   for(int i=0;i<100;i++){

      sum+=i;

      Print("Число равно:", i);

   }

   return(0);

}

1. В функциях всегда отвожу фигурным скобкам отдельные строки. В циклах/условиях первую фигурную скобку ставлю в первую строку.

2. Ненавижу очень распрастранненый стиль ставить фигурные скобки таким образом:

//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
  {
//----
   
//----

  return(0);
  }
//+------------------------------------------------------------------+

Комментарии //---- - вообще не понимаю.

3. Стараюсь объявлять переменную для итераций в самом цикле

4. Люблю использовать функции, стараюсь дробить программу на много частей. Однако жесткой привязке 20 строк на функцию нет. Считаю что функция должна выполнять локальную задачу. Задачи бывают большие бывают неочень, поэтому функция функции розень.

5. Использую функции в функции:

res=OrderSend(Symbol(),OP_BUY,GetVolume(GetPrice(OP_BUY),GetStopLossLevel(GetPrice(OP_BUY))),GetPrice(OP_BUY),3,GetStopLossLevel(GetPrice(OP_BUY)),GetTakeProfitLevel(GetPrice(OP_BUY)),"",GetMagicNumber(OP_BUY),0,Blue);


6. Использую функцию timing():

void Timing()
{
  //Здесь вызываем функции которые необходимо вызывать каждый тик
  //...
  //Здесь вызываем функции которые необходимо вызывать каждую минуту
  if(IsNewMinute()==true){  
  }
  //Здесь вызываем вункции которые достаточно вызывать каждый новый бар
  if(IsNewBar()==true){
     CheckForClosed();
     CheckForOpen();
  }
  //Здесь вызываем функции которые необходимо вызывать каждый новый день, например функцию для расчета свопов
  if(IsNewDay()==true){
  }
}

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

7. Не знаю почему, но почти всегда  использовать цикл for() а не while().

8. Ненавижу использовать вложенные условия:

if(param1==1){

   if(param2==2){

      if(param3==3){

         if(param4==4){

            if(param5==5){

               Print("Наконец-то дошли!");

            }

         }

      }

   }

}

Вместо этого использую такой код:

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

Print("Наконец-то дошли!");

Считаю такой способ гораздо удобней.
 

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

Print("Наконец-то дошли!");

В принципе нормальный код, выполняющий те же вычисления, что конструкция со вложенными if. Но вот где-то я слышал, что return в функции должен быть один. Наверно, для того, чтобы в них не запутаться. Я этому правилу не следую жестко.

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

 
C-4 >>:

2. Ненавижу очень распрастранненый стиль ставить фигурные скобки таким образом:

//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
  {
//----
   
//----
  return(0);
  }
//+------------------------------------------------------------------+

Комментарии //---- - вообще не понимаю.

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

if(param1==1){

   if(param2==2){

      if(param3==3){

         if(param4==4){

            if(param5==5){

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

--------

Ведь скобки нужны именно для обозначения составного оператора (блока), а не для обозначения тела цикла. Там где оператор не составной, скобки не использую:
//--Например, так:

if(param5==5) Print("Наконец-то дошли!");


//--Или так:

if(param5==5)
  Print("Наконец-то дошли!");

            

А если выделять составной оператор с открывающей скобкой где-то справа, зато закрывающую ставить слева, тогда:

//---Вот так многие поступают выделяя блок:

if(param5==5){
   Print("Наконец-то дошли!");
}


//--Т.е. блок выделяют вот так:

             {
   Print("Наконец-то дошли!");
}

---------------

Как кодить, где ставить скобки и т.п. - это дело вкуса каждого. Главное, чтобы программа была читаемой, не содержала ошибок, не нагружала систему (алгоритм должен быть оптимальным) и соответствовала тем критериям, для чего она написана.

 
Mathemat >>:

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

Да, есть такая. :)


Для зачистки кода я использую MetaQuotes Styler из двух файлов, которую нужно скачать по этой ссылке и развернуть в каталог /Windows/System32.

Запустить styler можно по команде:

mqstyler.exe /file:filename.mq4
mqstyler.exe /file:"long filename with spaces.mq4" (Если есть пробелы в названии)

 

я лично беру Visual Studio (VC++), копирую туда код MQL и форматирую по конвенции Microsoft, без тулзов. Как редактор кода VS тоже покруче (складка кода?). Может и можно комманду compile привинтить, но пока не пробовал.