Sobre el estilo de codificación - página 2

 

Aquí tienes que elegir una de las dos cosas:

1) Facilidad de escritura y legibilidad del código.

2) La velocidad de ejecución del programa.

Personalmente, siempre he preferido la segunda opción, por lo que intento declarar todas las variables de forma global y, si es posible, no utilizar funciones (hace tiempo que me di cuenta de su efecto en la velocidad de cálculo). Tiene que darse cuenta de que el Asesor Experto funcionará en su ordenador durante 24 horas al día, a veces necesita optimización y así sucesivamente. Por ello, la velocidad de los cálculos y el bajo consumo de recursos son muy importantes.

Y ahora veamos desde fuera los diferentes lenguajes de programación. Por ejemplo, Basic es fácil de codificar y de leer, pero la velocidad de cálculo... Ahora comparemos con C++. Aquí los polos ya han cambiado: es más difícil codificar (la legibilidad del código ha empeorado) pero la velocidad de cálculo ha aumentado mucho. Y si tomas Assembler, el código es casi ilegible.

Otra cosa es que es extraño cuando un programa escrito en el mismo lenguaje también cae bajo estos criterios y debe elegir - o la legibilidad del código o la velocidad de ejecución del programa (aunque no hay nada extraño, declarar una variable - consume tiempo; llamar una función y pasarle parámetros - consume tiempo). Pero es un hecho, que, por cierto, se notó no sólo en mql4...

 

Yo prefiero lo primero - quizás porque en MQL4 todavía no me he encontrado con casos en los que mis cálculos sean tan amplios que tenga que elegir entre legibilidad y velocidad. No estoy jugando con ticks, así que no necesito ninguna velocidad de cálculo loca.

Por otro lado, es difícil imaginar un EA que no tenga que modificar después.

 
Mathemat >> :

No juego a las garrapatas.

Aquí empiezan a surgir algunas características. Estoy totalmente de acuerdo: si se juega a precios de apertura, la arquitectura del programa debe cambiar. Por ejemplo, cuando se juega a precios de apertura no tiene sentido declarar variables a nivel global y mantenerlas en memoria hasta que aparezca la siguiente barra.

El estilo de codificación de un programa debe ser apropiado para su uso previsto. Aunque las reglas de codificación son las mismas en todas partes (funciones, variables, etc.), la frecuencia y el estilo de utilización de estas reglas en el código del programa dependen de las tareas finales específicas, es decir, para qué cálculos se utilizará el programa. Cada caso de uso de reglas de codificación requiere un enfoque diferente.

 

Muy recomendable: http://astyle.sourceforge.net/ es un formateador de texto C, pero hace un gran trabajo con MQ4.

un solo comando: AStyle.exe -b -t -p before.mq4 convierte el texto "empaquetado" en caramelo


 

Una utilidad similar fue ofrecida aquí hace mucho tiempo por los dueños del foro, ya sea aquí o en metaquotes. Pero ahora no tienes que buscarlo, gracias Sergey. Y el estilo de diseño es el mismo que yo prefiero.

 

En algún momento me pregunté "qué estilo de programación elegir". Como tenía poca experiencia, resolví el problema simplemente abriendo el código fuente de FreeBSD y mirando de cerca el estilo que utilizaban los programadores de la vieja escuela. En su momento, algunas cosas me parecieron inconvenientes, pero ahora entiendo por qué eligieron esas soluciones.

Así pues, estas son las reglas por las que escribo:

int main()

{

int sum;

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

sum+=i;

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

}

return(0);

}

1. En las funciones, siempre doy líneas separadas para las llaves. En los bucles/condiciones, pongo la primera llave en la primera línea.

2. Odio el estilo muy común de poner paréntesis rizados de esta manera:

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

//----

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

Comentarios //---- - No lo entiendo en absoluto.

3. Intento declarar una variable para las iteraciones en el propio bucle

4. Me gusta usar funciones, trato de dividir un programa en muchas partes. Pero no hay una obligación rígida de 20 líneas por función. Creo que una función debe realizar una tarea local. Las tareas a veces son grandes, a veces no tanto, por lo que la función es diferente.

5. Uso funciones dentro de una función:

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. Utilizo la función timing():

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

Como puede ver, incluso con el método de modelado por ticks, el bloque completo de cálculos no se establece cada ticks, sino que sólo se llama cuando es realmente necesario.

7. No sé por qué, pero casi siempre uso el bucle for() en lugar de while().

8. Odio usar condiciones anidadas:

if(param1==1){

if(param2==2){

if(param3==3){

if(param4==4){

if(param5==5){

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

}

}

}

}

}

En su lugar, utilizo un código como éste:

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

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

Me parece que esta forma es mucho más conveniente.
 

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

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

Básicamente, es un código normal que realiza los mismos cálculos que la construcción del if anidado. Pero en alguna parte he oído que el retorno en la función debe ser uno. Probablemente, se hace para no mezclarse con ellos. No sigo estrictamente esta regla.

Por lo demás, mi planteamiento es muy parecido al tuyo, C-4, salvo un par de detalles.

 
C-4 >> :

2. Odio el estilo tan común de poner tirantes así:

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

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

Comentarios //---- - No lo entiendo en absoluto.

Yo, en cambio, prefiero este estilo: no hay que buscar corchetes al final de una línea. Muchas personas pierden los corchetes por esta misma razón (olvidando poner un paréntesis de cierre), o por el contrario, hacen corchetes de cierre de más. Pero, en general, es una cuestión de gustos: cada persona tiene una letra diferente en el papel. Y cada uno escribe las notas de forma diferente (alguien hace una nota a pie de página, alguien subraya, alguien hace una sangría) - lo principal que el autor del cuaderno era fácil de percibir la información de un vistazo. La sintaxis del lenguaje permite poner llaves en cualquier lugar, incluso en una línea. Pero por alguna razón nadie pone llaves de cierre así:

if( param1==1){

   if( param2==2){

      if( param3==3){

         if( param4==4){

            if( param5==5){

               Print("Наконец-то дошли!");}}}}}
Por eso no guardo espacio para una línea de código separada: todos los paréntesis (tanto de apertura como de cierre) están a la izquierda de los demás (con sangrías para cada bloque adjunto siguiente, al estilo de la espiga) y de un vistazo se puede estimar el comienzo y el final de un operador compuesto (bloque), por muy inteligente y sofisticado que sea el programa. :)

--------

Al fin y al cabo, los paréntesis se utilizan sólo para designar un operador compuesto (bloque) y no para designar el cuerpo del bucle. No utilizo paréntesis cuando el operador no es compuesto:
//--Например, так:

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


//--Или так:

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

            

Y si seleccionas un operador compuesto con un paréntesis de apertura en algún lugar de la derecha, pero pones paréntesis de cierre a la izquierda, entonces

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

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


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

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

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

Cómo codificar, dónde poner paréntesis, etc. - es una cuestión de gusto de cada uno. Lo principal es que el programa sea legible, no tenga errores, no se cargue el sistema (el algoritmo debe ser óptimo) y cumpla los criterios para los que está escrito.

 
Mathemat >> :

Una herramienta similar fue ofrecida aquí por los propietarios del foro hace mucho tiempo - ya sea aquí o en metaquotes. Pero ahora no tienes que buscarlo. Y el estilo de diseño es el mismo, como yo lo prefiero.

Sí, hay uno. :)


Para la limpieza del código uso MetaQuotes Styler de dos archivos que puedes descargar desde este enlace y colocar en el directorio /Windows/System32.

Puede ejecutar el estilizador mediante el comando

mqstyler.exe /file:filename.mq4
mqstyler.exe /file: "long filename with spaces.mq4" (Si hay espacios en el nombre)

 

Yo personalmente tomo Visual Studio (VC++), copio el código MQL allí y lo formateo según la convención de Microsoft, sin herramientas. Como editor de código, VS también es más genial (¿plegado de código?). Tal vez sea posible atornillar un comando de compilación, pero aún no lo he probado.

Razón de la queja: