Sullo stile di codifica - pagina 2

 

Qui devi scegliere una delle due cose:

1) Facilità di scrittura e facile leggibilità del codice.

2) La velocità di esecuzione del programma.

Personalmente, ho sempre preferito la seconda opzione, quindi cerco di dichiarare tutte le variabili globalmente e, se possibile, di non usare funzioni (ho notato il suo effetto sulla velocità di calcolo molto tempo fa). Devi renderti conto che l'Expert Advisor funzionerà sul tuo computer per 24 ore al giorno, a volte ha bisogno di ottimizzazione e così via. Pertanto, la velocità dei calcoli e il basso consumo di risorse sono molto importanti.

E ora guardiamo dall'esterno i diversi linguaggi di programmazione. Per esempio, Basic è facile da codificare e facile da leggere, ma la velocità di calcolo... Ora confrontiamo il C++ con esso. Qui i poli sono già cambiati - è più difficile da codificare (la leggibilità del codice è peggiorata) ma la velocità di calcolo è molto aumentata. E se si prende Assembler, il codice è quasi illeggibile.

Un'altra cosa è che è strano quando anche un programma scritto nello stesso linguaggio rientra in questi criteri e si deve scegliere tra la leggibilità del codice o la velocità di esecuzione (anche se non c'è niente di strano, dichiarare una variabile - richiede tempo; chiamare una funzione e passarle dei parametri - richiede tempo). Ma è un fatto, che tra l'altro è stato notato non solo in mql4...

 

Preferisco il primo - forse perché in MQL4 non ho ancora incontrato casi in cui i miei calcoli sono così vasti da dover scegliere tra leggibilità e velocità. Non sto giocando con le zecche, quindi non ho bisogno di una velocità di calcolo pazzesca.

D'altra parte, è difficile immaginare un EA che non debba modificare in seguito.

 
Mathemat >> :

Non gioco con le zecche.

Qui cominciano ad emergere alcune caratteristiche. Sono assolutamente d'accordo - se si gioca a prezzi di apertura, allora l'architettura del programma deve cambiare. Per esempio, quando si gioca a prezzi di apertura non ha senso dichiarare variabili a livello globale e tenerle in memoria fino alla comparsa della prossima barra.

Lo stile di codifica di un programma deve essere appropriato per l'uso previsto. Anche se le regole di codifica sono le stesse ovunque (funzioni, variabili, ecc.), la frequenza e lo stile di utilizzo di queste regole nel codice del programma dipende dai compiti finali specifici - per quali calcoli il programma sarà usato. Ogni caso di utilizzo di regole di codifica richiede un approccio diverso.

 

altamente raccomandato: http://astyle.sourceforge.net/ è un formattatore di testo C, ma fa un ottimo lavoro con MQ4.

un solo comando: AStyle.exe -b -t -p before.mq4 trasforma il testo "confezionato" in caramelle


 

Un'utilità simile è stata offerta qui molto tempo fa dai proprietari del forum, qui o su metaquotes. Ma ora non c'è bisogno di cercarlo, grazie Sergey. E lo stile del design è lo stesso che preferisco io.

 

Un tempo mi chiedevo "quale stile di programmazione scegliere". Avendo poca esperienza, ho risolto il problema semplicemente aprendo il codice sorgente di FreeBSD e guardando da vicino lo stile che i programmatori della vecchia scuola usavano. All'epoca, alcune cose mi sembravano scomode, ma ora capisco perché hanno scelto queste soluzioni.

Quindi, ecco le regole con cui scrivo:

int main()

{

int sum;

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

sum+=i;

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

}

return(0);

}

1. Nelle funzioni, do sempre linee separate per le parentesi graffe. Nei cicli/condizioni, metto la prima parentesi graffa nella prima riga.

2. Odio lo stile molto comune di mettere le parentesi graffe in questo modo:

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

//----

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

Commenti //---- - Non lo capisco affatto.

3. Provo a dichiarare una variabile per le iterazioni nel ciclo stesso

4. Mi piace usare le funzioni, cerco di dividere un programma in molte parti. Ma non c'è un vincolo rigido di 20 linee per funzione. Credo che una funzione debba eseguire un compito locale. I compiti sono a volte grandi, a volte non così grandi, quindi la funzione è diversa.

5. Uso funzioni all'interno di una funzione:

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. Uso la funzione timing():

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

Come potete vedere, anche con il metodo di modellazione tickwise, l'intero blocco di calcoli non è impostato ogni tick, ma è chiamato solo quando è veramente necessario.

7. Non so perché, ma quasi sempre uso il ciclo for() invece di while().

8. Odio usare condizioni annidate:

if(param1==1){

if(param2==2){

if(param3==3){

if(param4==4){

if(param5==5){

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

}

}

}

}

}

Io invece uso un codice come questo:

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

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

Trovo questo modo molto più conveniente.
 

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

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

Fondamentalmente, è un codice normale che esegue gli stessi calcoli della costruzione if annidata. Ma da qualche parte ho sentito che il ritorno nella funzione dovrebbe essere uno. Probabilmente, è fatto per evitare di confondersi con loro. Non seguo strettamente questa regola.

Per il resto il mio approccio è molto vicino al tuo, C-4, tranne un paio di dettagli.

 
C-4 >> :

2. Odio lo stile molto comune di mettere le bretelle in questo modo:

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

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

Commenti //---- - Non lo capisco affatto.

Io, invece, preferisco questo stile: non devi cercare le parentesi graffe alla fine di una riga. Molte persone perdono le parentesi proprio per questo motivo (dimenticando di mettere una parentesi di chiusura), o al contrario, fanno delle parentesi di chiusura extra. Ma in generale, è una questione di gusto - ognuno ha una scrittura diversa sulla carta. E ognuno scrive le note in modo diverso (qualcuno fa una nota a piè di pagina, qualcuno sottolinea, qualcuno indenta) - la cosa principale che l'autore del notebook era facile da percepire le informazioni a colpo d'occhio. La sintassi del linguaggio permette di mettere le parentesi graffe ovunque, anche in una riga. Ma per qualche motivo nessuno mette le parentesi graffe di chiusura in questo modo:

if( param1==1){

   if( param2==2){

      if( param3==3){

         if( param4==4){

            if( param5==5){

               Print("Наконец-то дошли!");}}}}}
Questo è il motivo per cui non risparmio spazio per una linea separata di codice - tutte le parentesi (sia di apertura che di chiusura) sono a sinistra l'una dell'altra (con rientri per ogni successivo blocco racchiuso, stile spina di pesce) e a colpo d'occhio si può valutare l'inizio e la fine di un operatore composto (blocco), non importa quanto intelligente e sofisticata sia una parte di programma. :)

--------

Dopo tutto, le parentesi sono usate solo per designare un operatore composto (blocco) e non per designare il corpo del ciclo. Non uso le parentesi dove l'operatore non è composto:
//--Например, так:

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


//--Или так:

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

            

E se selezionate un operatore composto con una parentesi di apertura da qualche parte a destra, ma mettete le parentesi di chiusura a sinistra, allora

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

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


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

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

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

Come codificare, dove mettere le parentesi, ecc. - è una questione di gusti. La cosa principale è che il programma deve essere leggibile, senza errori, non caricare il sistema (l'algoritmo deve essere ottimale) e soddisfare i criteri per cui è scritto.

 
Mathemat >> :

Lo strumento simile è stato offerto qui dai proprietari del forum molto tempo fa - o qui o su metaquotes. Ma ora non c'è bisogno di cercarlo. E lo stile del design è lo stesso, come lo preferisco.

Sì, ce n'è uno. :)


Per la pulizia del codice uso MetaQuotes Styler da due file che puoi scaricare da questo link e mettere nella directory /Windows/System32.

Potete eseguire lo styler con il comando:

mqstyler.exe /file:filename.mq4
mqstyler.exe /file: "long filename with spaces.mq4" (se ci sono spazi nel nome)

 

Personalmente prendo Visual Studio (VC++), ci copio il codice MQL e lo formatto secondo la convenzione Microsoft, senza strumenti. Come editor di codice VS è anche più figo (piegatura del codice?). Potrebbe essere possibile avvitare un comando di compilazione, ma non ho ancora provato.

Motivazione: