Errori, bug, domande - pagina 577

 
papaklass:

...

Ok. La sua posizione è chiara.
 

È persino difficile immaginare un tale Expert Advisor che manca della potenza di un nucleo nella vita reale. Per esempio, se nel tester l'Expert Advisor fa un passaggio di un simbolo al giorno sullo storico di un anno (è troppo! Forse dovremmo riscrivere il codice!), allora nella vita reale, caricherà la CPU in media 1/250 della potenza = 0,4%.

Per un EA su dieci simboli - si ottiene un carico medio del 4%. Non ha molto senso caricare gli altri core.

 

Per quanto riguarda l'idea di Konstantin(Lizar), penso che sia buona. Ma per questo tipo di soluzione abbiamo bisogno di separare gli eventi che provengono direttamente dal grafico e quelli che sono generati in modo personalizzato. Per gli eventi personalizzati, possiamo avere due code di eventi e due gestori di eventi, qualcosa come OnUserEvents.

E un'aggiunta interessante agli eventi personalizzati sarebbe la possibilità di specificare esplicitamente la loro priorità (diciamo da 0 a 9), il che potrebbe permettere all'utente di controllare la precedenza e la gestione di certi eventi. Per esempio, una tale caratteristica permetterebbe di eseguire gli eventi con un valore più basso, e rimuoverli dalla coda con un valore più alto (se la coda è piena di eventi più importanti, non ne verrebbero accodati di nuovi).

papaklass:

Non ho mai fatto sviluppo di software, quindi non posso parlare il linguaggio tecnico degli sviluppatori di software. Descrivo ciò che vorrei ottenere dal mio computer a 4 core e dalla MT5. In generale si presenta così:


La gestione di diversi strumenti è ora possibile e gli sviluppatori hanno creato una soluzione perfettamente funzionante.

2. Circa il lavoro del tester e un mucchio di core. Si tratta di un caso speciale e non è corretto confrontare questo meccanismo con il trading reale. L'essenza della soluzione del problema del tester è che avendo diverse varianti di Expert Advisor (o piuttosto un Expert Advisor + un sacco di set di parametri unici) è ragionevole distribuire i calcoli tra tutti i core/agenti disponibili. Così si ottiene l'asincronia per tutto l'insieme dei compiti, ma dal punto di vista di un singolo agente tutto è sincronizzato.

3. Quando si parla di multithreading, non stiamo parlando di elaborare più strumenti allo stesso tempo, ma di elaborare più eventi allo stesso tempo (e all'interno di un singolo agente specifico). Questo non era presente in nessuna versione del terminale.

Anche gli sviluppatori sono comprensibili: troppo overhead, mix troppo "eterogeneo" di utenti, troppi problemi con la sincronizzazione dei dati a cui un Expert Advisor "multi-threaded" avrà accesso, ecc.

D'altra parte, l'idea con gli eventi non è portata alla sua conclusione logica. Ok, è costoso e problematico implementare il "multithreading", ma è possibile parallelizzare al massimo i processi e i flussi di informazioni all'interno del terminale stesso + creare un insieme di gestori sufficiente a risolvere il numero massimo di compiti (e con un normale insieme di parametri).

 
papaklass:

Il mio Expert Advisor su M5, nel periodo 04.01.2010 - 01.09.2011 su 12 valute fa un solo passaggio in 1436 sec (24 minuti) e allo stesso tempo fa 5687 trade. Solo un core è caricato, gli altri tre sono inattivi. Cioè, ad ogni singolo passaggio perdo 3/4 del tempo perché la piattaforma non usa la potenza del computer. Questo è uno svantaggio significativo della piattaforma quando si fa il debug di una strategia. I core sono completamente utilizzati solo durante l'ottimizzazione. Ma l'ottimizzazione è molto più rara delle corse singole. E un sacco di tempo viene sprecato in corse singole.

L'approccio "perdere 3/4 del tempo" indica che tu credi: usare il multithreading è solo un'opportunità mancata e un chiaro difetto degli sviluppatori.

Sfortunatamente, il multi-threading su compiti sequenziali (e un singolo passaggio del tester è un compito sequenziale) non è dato gratuitamente. In realtà, il multi-threading ha enormi perdite (a volte multiple) per la sincronizzazione dei processi. Infatti, tutti gli accessi alle risorse condivise devono essere legati con dei sincronizzatori.

Abbiamo deliberatamente spostato il tester fuori dal terminale in un processo separato solo per permettergli di lavorare in un singolo thread senza blocchi per il 99% del tempo di test. Il risultato è stato un significativo guadagno di velocità.

Il suggerimento "ficchiamo il multitasking in ogni EA" deriva da una completa incomprensione del costo (rallentamento totale) del multithreading in questo caso e delle conseguenze (rallentamento + far saltare il tetto al 99% degli sviluppatori non professionisti).


Abbiamo risolto efficacemente i problemi di applicazione del multitasking nel terminale, nel tester e abilitato una scalabilità quasi illimitata della potenza nelle modalità agente remoto e MQL5 Cloud Network.


Se apro 12 grafici e metto un indicatore su ognuno di essi, allora posso vedere come il terminale ritarda in certi momenti. A giudicare dai messaggi sul forum, non succede solo a me. Quindi, sono 12 strumenti con un indicatore, e se ho bisogno di aumentare il numero di strumenti e indicatori, il terminale si blocca. E un nucleo sarà utilizzato, mentre il resto riposerà. Quindi, ha senso caricare altri core? Se distribuiamo i processi terminali tra i core, cioè utilizziamo pienamente la potenza del computer, saremo in grado di risolvere compiti ad un altro livello. Questo è quello che voglio dire.

Se ci sono 12 carte diverse con simboli diversi, significa che ogni simbolo di ogni char è ovviamente in esecuzione nel proprio thread senza influenzare gli altri.

Se i grafici iniziano a rallentare, la ragione è banale - uno degli indicatori è molto antieconomico. In questo caso, nessuna quantità di multitasking aiuterà, perché la radice è il lavoro del programmatore, che scrive indicatori nella testa, non curandosi dell'efficienza.

 

Non posso ottenere il grafico inverso, c'è qualcosa di sbagliato, la nuova barra glitch su questa variante

l'indicatore originale con cui ho giocherellato è allegato

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---- проверка количества баров на достаточность для расчета
   for(int numb=0; numb<8; numb++) if(BarsCalculated(RSI_Handle[numb])<rates_total) return(RESET);
   if(rates_total<min_rates_total) return(RESET);

//---- объявления локальных переменных 
   int to_copy;

//---- расчеты необходимого количества копируемых данных
   if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчета индикатора
      to_copy=rates_total-1;                   // стартовый номер для расчета всех баров
   else to_copy=rates_total-prev_calculated+1; // стартовый номер для расчета новых баров
   
//---- копируем вновь появившиеся данные в массивы
   if(CopyBuffer(RSI_Handle[0],0,0,to_copy,Buffer1)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[1],0,0,to_copy,Buffer2)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[2],0,0,to_copy,Buffer3)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[3],0,0,to_copy,Buffer4)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[4],0,0,to_copy,Buffer5)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[5],0,0,to_copy,Buffer6)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[6],0,0,to_copy,Buffer7)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[7],0,0,to_copy,Buffer8)<=0) return(RESET);
   
   //мой кусок отсель   
   if (Reverse)
      {
         int start=prev_calculated;
         for(int i=start;i<rates_total;i++)
            {
               Buffer1[i]=100-Buffer1[i];
               Buffer2[i]=100-Buffer2[i];
               Buffer3[i]=100-Buffer3[i];
               Buffer4[i]=100-Buffer4[i];
               Buffer5[i]=100-Buffer5[i];
               Buffer6[i]=100-Buffer6[i];
            }
         Buffer1[0]=100-Buffer1[0];
         Buffer2[0]=100-Buffer2[0];
         Buffer3[0]=100-Buffer3[0];
         Buffer4[0]=100-Buffer4[0];
         Buffer5[0]=100-Buffer5[0];
         Buffer6[0]=100-Buffer6[0];
       }  
   //досель    

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

File:
Multi_RSI.mq5  15 kb
 

Per favore, consigliatemi qual è il problema.

Sto scrivendo un multivaluta

Ottengo la maniglia dell'indicatore MA

maHandle_EURUSD=iMA("EURUSD",PERIOD_H1,MA_Period_EURUSD,MA_Shift_EURUSD,MODE_SMA,PRICE_CLOSE);

maHandle_GBPUSD=iMA("GBPUSD",PERIOD_H1,MA_Period_GBPUSD,MA_Shift_GBPUSD,MODE_SMA,PRICE_CLOSE); 

Sto facendo lo stesso per le restanti 10 valute permesse nel campionato, ma ottengo l'errore 4801 durante il test, tutte le 12 valute sono nella storia (credo)

Sto testando sul grafico EURUSD

l'Expert Advisor sta testando GBPUSD (l'ho impostato così nelle impostazioni, per ottimizzarlo)

 
Lazarev:

Per favore, consigliatemi qual è il problema.

Sto scrivendo un multivaluta

Ottengo la maniglia dell'indicatore MA

Sto facendo lo stesso per le restanti 10 valute permesse nel campionato, ma ottengo l'errore 4801 durante il test, tutte le 12 valute sono nella storia (credo)

Sto testando sul grafico EURUSD

l'Expert Advisor sta testando GBPUSD (l'ho impostato così nelle impostazioni, per ottimizzarlo)

Ho bisogno di aggiungere simboli aSymbolSelect Market Watch
 

papaklass:

Ora rispondi a una domanda così semplice ....

Risponderò ancora più semplicemente, anche se non educatamente.

Purtroppo, sei completamente fuori tema e fai affermazioni che mostrano solo idee superficiali sui processi.

Temo che la maggior parte dei nostri argomenti tecnici non saranno capiti, e nemmeno il problema fondamentale della sincronizzazione e la perdita sulla sua fornitura.

Quindi, non c'è bisogno di fare richieste "tu ci dici i tuoi argomenti e noi speculiamo", la situazione è perfettamente chiara

 

Non riesco a trovare nessuna risposta a queste domande per un principiante:

1) Quando si aggiunge un altro elemento a un array dinamico, è necessario espanderlo con ArrayResize?

2) C'è una funzione in MQL5 per cancellare un elemento (uno nel mezzo di una matrice, per esempio) da una matrice dinamica i? Se no, qual è il modo migliore per farlo?

Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Fia:

Come novellino, non riesco a trovare nessuna risposta a queste domande:

1) Quando si aggiunge un altro elemento a un array dinamico, è necessario espanderlo con ArrayResize?

Si fa la dimensione dell'array con una certa riserva, quando ci si avvicina al limite si aumenta la dimensione. Non c'è nessun ridimensionamento e aggiunta automatica alla fine. Guardate l'esempio della funzione ArrayInitialize()
Motivazione: