Sobre o estilo de codificação - página 2

 

Aqui você tem que escolher uma de duas coisas:

1) Facilidade de escrita e facilidade de leitura do código.

2) Velocidade de execução do programa.

Pessoalmente, sempre preferi a segunda opção, portanto tento declarar todas as variáveis globalmente e, se possível, não usar funções (notei seu efeito sobre a velocidade computacional há muito tempo). Você tem que perceber que o Expert Advisor funcionará em seu computador por 24 horas por dia, às vezes ele precisa de otimização e assim por diante. Portanto, a velocidade dos cálculos e o baixo consumo de recursos são muito importantes.

E agora vamos olhar de fora para diferentes linguagens de programação. Por exemplo, Basic é fácil de codificar e fácil de ler, mas a velocidade de cálculo... Agora vamos comparar o C++ com ele. Aqui os pólos já mudaram - é mais difícil codificar (a legibilidade do código se tornou pior), mas a velocidade de cálculo aumentou muito. E se você pegar Assembler, o código é quase ilegível.

Outra coisa é que é estranho quando um programa escrito na mesma língua também se enquadra nestes critérios e você tem que escolher entre legibilidade de código ou velocidade de execução (embora não haja nada estranho, para declarar uma variável - demorada; para chamar uma função e passar parâmetros para ela - demorada). Mas é um fato, que, a propósito, não só foi notado em mql4.

 

Prefiro o primeiro - talvez porque na MQL4 ainda não encontrei casos em que meus cálculos sejam tão vastos que eu tenha que escolher entre legibilidade e velocidade. Não estou brincando com carrapatos, por isso não preciso de nenhuma velocidade de cálculo maluca.

Por outro lado, é difícil imaginar uma EA que eu não tenha que modificar mais tarde.

 
Mathemat >> :

Eu não jogo carrapatos.

Aqui, algumas características estão começando a surgir. Concordo plenamente - se você joga a preços de abertura, então a arquitetura do programa deve mudar. Por exemplo, ao jogar com preços de abertura não faz sentido declarar variáveis em nível global e mantê-las na memória até a próxima barra aparecer.

O estilo de codificação de um programa deve ser apropriado para seu uso pretendido. Embora as regras de codificação sejam as mesmas em todos os lugares (funções, variáveis, etc.), a freqüência e o estilo de utilização destas regras no código do programa depende das tarefas finais específicas - para quais cálculos o programa será utilizado. Cada caso de uso de regras de codificação requer uma abordagem diferente.

 

altamente recomendado: http://astyle.sourceforge.net/ é um formatador de texto C, mas faz um ótimo trabalho com o MQ4.

apenas um comando: AStyle.exe -b -t -p antes.mq4 transforma texto "empacotado" em balas


 

Uma utilidade semelhante foi oferecida aqui há muito tempo pelos proprietários do fórum, seja aqui ou em metaquotas. Mas agora você não precisa procurá-lo, graças a Sergey. E o estilo de design é o mesmo que eu prefiro.

 

Em algum momento me perguntei "que estilo de programação escolher". Como eu tinha pouca experiência, resolvi o problema simplesmente abrindo o código fonte do FreeBSD e analisando de perto o estilo que os programadores da Old School estavam usando. Na época, algumas coisas me pareceram inconvenientes, mas agora entendo porque eles escolheram tais soluções.

Portanto, aqui estão as regras pelas quais eu escrevo:

int main()

{

int sum;

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

sum+=i;

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

}

return(0);

}

1. Em funções, sempre dou linhas separadas para parênteses encaracolados. Em loops/condições, coloquei o primeiro parênteses na primeira linha.

2. Odeio o estilo muito comum de colocar parênteses encaracolados desta maneira:

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

//----

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

Comentários //---- - Eu não entendo nada.

3. Eu tento declarar uma variável para iterações no próprio loop

4. Eu gosto de usar funções, eu tento dividir um programa em muitas partes. Mas não há uma ligação rígida de 20 linhas por função. Acredito que uma função deve desempenhar uma tarefa local. As tarefas às vezes são grandes, às vezes não tão grandes, por isso a função é diferente.

5. Eu uso funções dentro de uma função:

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. Eu utilizo a função de tempo():

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

Como você pode ver, mesmo com o método de modelagem tickwise, o bloco inteiro de cálculos não é definido a cada tick, mas é chamado apenas quando é realmente necessário.

7. Não sei por que, mas quase sempre uso o laço for() em vez de while().

8. Eu odeio usar condições aninhadas:

if(param1==1){

if(param2==2){

if(param3==3){

if(param4==4){

if(param5==5){

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

}

}

}

}

}

Em vez disso, uso código como este:

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

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

Acho este caminho muito mais conveniente.
 

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

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

Basicamente, é o código normal que realiza os mesmos cálculos que o aninhado se construção. Mas em algum lugar eu ouvi dizer que o retorno na função deveria ser um. Provavelmente, isso é feito para não se misturar neles. Eu não sigo estritamente esta regra.

Quanto ao resto, minha abordagem é muito próxima à sua, C-4, exceto por alguns detalhes.

 
C-4 >> :

2. Odeio o estilo muito comum de colocar aparelhos como este:

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

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

Comentários //---- - Eu não entendo nada.

Eu, por outro lado, prefiro este estilo: não é preciso procurar parênteses encaracolados no final de uma linha. Muitas pessoas perdem o aparelho por esta mesma razão (esquecendo-se de colocar um parêntese de fechamento), ou pelo contrário, fazem aparelhos de fechamento extras. Mas em geral, é uma questão de gosto - cada um tem uma caligrafia diferente no papel. E todos escrevem notas de forma diferente (alguém faz uma nota de rodapé, alguém sublinha, alguém trava) - o principal é que o autor do caderno foi fácil de perceber a informação num relance. A sintaxe do idioma permite que você ponha o aparelho em qualquer lugar - mesmo em uma linha. Mas, por alguma razão, ninguém coloca um aparelho de fechamento como este:

if( param1==1){

   if( param2==2){

      if( param3==3){

         if( param4==4){

            if( param5==5){

               Print("Наконец-то дошли!");}}}}}
É por isso que não guardo espaço para uma linha de código separada - todos os colchetes (tanto de abertura quanto de fechamento) estão do lado esquerdo um do outro (com recuos para cada bloco seguinte, estilo herringbone) e num relance você pode estimar o início e o fim de um operador composto (bloco), não importa o quão inteligente e sofisticado seja uma parte do programa. :)

--------

Afinal, são usados parênteses apenas para designar um operador composto (bloco) e não para designar o corpo do laço. Eu não uso parênteses onde o operador não é composto:
//--Например, так:

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


//--Или так:

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

            

E se você selecionar um operador composto com um suporte de abertura em algum lugar à direita, mas colocar os suportes de fechamento à esquerda, então

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

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


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

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

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

Como codificar, onde colocar parênteses, etc. - é uma questão do gosto de todos. O principal é que o programa deve ser legível, livre de erros, não carregar o sistema (o algoritmo deve ser ótimo) e atender aos critérios para os quais está escrito.

 
Mathemat >> :

A ferramenta similar foi oferecida aqui pelos donos do fórum há muito tempo - seja aqui ou em metaquotas. Mas agora você não precisa procurar por ela. E o estilo de design é o mesmo, como eu prefiro.

Sim, existe um. :)


Para a limpeza do código eu uso MetaQuotes Styler de dois arquivos que você pode baixar deste link e colocar no diretório /Windows/System32.

Você pode executar o modelador pelo comando:

mqstyler.exe /file:filename.mq4
mqstyler.exe /file: "long filename with spaces.mq4" (Se houver espaços no nome)

 

Eu pessoalmente levo o Visual Studio (VC++), copio lá o código MQL e o formato de acordo com a convenção da Microsoft, sem ferramentas. Como um editor de código VS também é mais legal (código dobrável?). Pode ser possível parafusar um comando de compilação, mas eu ainda não o tentei.