English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
3 Metodi di accelerazione degli indicatori mediante l'esempio della regressione lineare

3 Metodi di accelerazione degli indicatori mediante l'esempio della regressione lineare

MetaTrader 5Indicatori | 17 dicembre 2021, 15:32
227 0
ds2
ds2


Velocità dei calcoli

Il calcolo rapido degli indicatori è un compito di vitale importanza. I calcoli possono essere accelerati con metodi diversi. Ci sono molti articoli su questo problema.

E ora esamineremo altri 3 metodi per accelerare i calcoli e talvolta anche per semplificare un codice stesso. Tutti i metodi descritti sono algoritmici, ovvero non ridurremo la profondità della cronologia né abiliteremo i core aggiuntivi dell'unità del processore. Ottimizzeremo direttamente gli algoritmi di calcolo.


Indicatore di base

L'indicatore che deve essere utilizzato per la visualizzazione di tutti e 3 i metodi è un lineare di regressione. Crea una funzione di regressione su ogni barra (in base al numero definito delle ultime barre) e mostra quale valore deve avere su quella barra. Di conseguenza, abbiamo una linea continua:

Ecco come appare l'indicatore nel terminale

 

L'equazione di regressione lineare ha il seguente aspetto:


Nel nostro caso, x è un numero di barre e y sono i prezzi.

I rapporti dell'equazione menzionata sono calcolati come segue:


dove N è un numero delle barre utilizzate per formare la retta di regressione.

Ecco come appaiono queste equazioni in MQL5 (all'interno del ciclo di tutte le barre della cronologia):

            // Finding intermediate values-sums
            Sx  = 0;
            Sy  = 0;
            Sxx = 0;
            Sxy = 0;
            for (int x = 1; x <= LRPeriod; x++)
              {
               double y = price[bar-LRPeriod+x];
               Sx  += x;
               Sy  += y;
               Sxx += x*x;
               Sxy += x*y;
              }

            // Regression ratios
            double a = (LRPeriod * Sxy - Sx * Sy) / (LRPeriod * Sxx - Sx * Sx);
            double b = (Sy - a * Sx) / LRPeriod;

            lrvalue = a*LRPeriod + b;

Il codice completo dell'indicatore è allegato all'articolo. Contiene anche tutti i metodi descritti nel presente articolo. Pertanto, nelle impostazioni dell'indicatore, si deve selezionare il metodo di calcolo "Standard":

Eng_G0-Standard

Finestra di impostazione dei parametri di input dell'indicatore quando è impostato sul grafico 


Il Primo metodo. Ottimizzazione. Totali mobili

C'è un'enorme quantità di indicatori in cui viene calcolata una cifra totale di alcuni valori di sequenza di barre in ciascuno di essi. E questa sequenza cambia costantemente ad ogni battuta. L'esempio più noto è la media mobile (MA). Calcola una somma delle ultime N barre e poi questo valore viene diviso per il loro numero.

Penso che solo una piccola quantità di persone sappia che esiste un modo elegante per accelerare considerevolmente il calcolo di questi totali mobili. Utilizzo questo metodo nei miei indicatori già da molto tempo, quando ho scoperto che t viene utilizzato anche nei normali indicatori MA di MetaTrader 4 e 5. (Non è il primo caso in cui trovo che gli indicatori MetaTrader siano adeguatamente ottimizzati dagli sviluppatori. Molto tempo fa stavo cercando indicatori ZigZag veloci e un indicatore regolare si è rivelato più efficace della maggior parte di quelli esterni. A proposito, l'argomento del forum menzionato contiene anche metodi di ottimizzazione ZigZag, nel caso in cui qualcuno ne abbia bisogno).

E ora torniamo ai totali mobili. Confrontiamo i totali calcolati per due barre adiacenti. La figura seguente mostra che questi totali hanno una parte comune considerevole (mostrata in verde). Il totale calcolato per la barra 0 differisce dal totale per la barra 1 solo per il fatto che il totale non include una barra obsoleta (quella rossa a sinistra) ma include una nuova barra (quella blu a destra):

Eng_m1

Valori esclusi e inclusi nel totale durante uno spostamento di una barra

 

Pertanto, non è necessario sommare nuovamente tutte le barre necessarie durante il calcolo del totale per la barra 0. Possiamo solo prendere una somma dalla barra 1, sottrarre un valore e aggiungerne uno nuovo. Sono necessarie solo due operazioni aritmetiche. Utilizzando tale metodo possiamo accelerare notevolmente il calcolo degli indicatori.

Nella Media Mobile tale metodo viene utilizzato di routine, in quanto l'indicatore mantiene tutti i valori medi nel suo unico buffer. E questo non è altro che i totali divisi per N, cioè il numero di barre incluse nel totale. Moltiplicando un valore dal buffer per N, possiamo ottenere facilmente un totale per qualsiasi barra e applicare il metodo sopra descritto.

Ora ti mostrerò come applicare questo metodo nell'indicatore più complicato: la regressione lineare. Hai già visto che le equazioni per il calcolo dei rapporti delle funzioni di regressione contengono quattro totali: x, y, x*x, x*y. Il calcolo di tali totali deve essere memorizzato nel buffer. I buffer per ciascun totale nell'indicatore devono essere assegnati per raggiungere questo obiettivo:

double ExtBufSx[], ExtBufSy[], ExtBufSxx[], ExtBufSxy[];

Il buffer potrebbe non essere necessariamente visto su un grafico. MetaTrader 5 ha uno speciale tipo di buffer per calcoli intermedi. Lo useremo per assegnare i numeri di buffer su OnInit:

   SetIndexBuffer(1, ExtBufSx,  INDICATOR_CALCULATIONS);
   SetIndexBuffer(2, ExtBufSy,  INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, ExtBufSxx, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, ExtBufSxy, INDICATOR_CALCULATIONS);

Il codice di calcolo della regressione lineare standard cambierà per quanto segue ora:

            // (The very first bar was calculated using the standard method)        
        
            // Previous bar
            int prevbar = bar-1;
            
            //--- Calculating new values of intermediate totals 
            //    from the previous bar values
            
            Sx  = ExtBufSx [prevbar]; 
            
            // An old price comes out, a new one comes in
            Sy  = ExtBufSy [prevbar] - price[bar-LRPeriod] + price[bar]; 
            
            Sxx = ExtBufSxx[prevbar];
            
            // All the old prices come out once, a new one comes in with an appropriate weight
            Sxy = ExtBufSxy[prevbar] - ExtBufSy[prevbar] + price[bar]*LRPeriod;
            
            //---

            // Regression ratios (calculated the same way as in the standard method)
            double a = (LRPeriod * Sxy - Sx * Sy) / (LRPeriod * Sxx - Sx * Sx);
            double b = (Sy - a * Sx) / LRPeriod;

            lrvalue = a*LRPeriod + b;

Il codice completo dell'indicatore è allegato all'articolo. Il metodo di calcolo "Totali mobili" deve essere impostato nelle impostazioni dell'indicatore.


Il second metodo. Semplificazione

Questo metodo sarà apprezzato dai fan della matematica. Nelle equazioni complicate si possono spesso trovare frammenti che sembrano essere le parti giuste di altre equazioni conosciute. Ciò dà la possibilità di sostituire quei frammenti con le loro parti sinistre (che di solito consistono in una sola variabile). In altre parole, possiamo semplificare un'equazione complicata. E può sembrare che alcuni elementi di questa equazione semplificata siano già realizzati come indicatori. In tal caso, il codice dell'indicatore contenente tale equazione può essere a sua volta notevolmente semplificato.

Di conseguenza, abbiamo almeno un codice più semplice e meno ingombrante. E a volte può anche essere più veloce, come nel caso in cui gli indicatori implementati nel codice siano ben ottimizzati per la velocità.

Sembra che anche l'equazione di regressione lineare possa essere semplificata e il suo calcolo possa essere sostituito con l'inizializzazione di diversi indicatori standard MetaTrader 5. Molti dei suoi elementi sono calcolati nell'indicatore Media Mobile nelle sue diverse modalità di calcolo:

  • la somma y è presente nella Media Mobile Semplice:

  • la somma x*y è presente nella Media Mobile ponderata lineare:

Si noti che l'equazione per LWMA è vera solo nel caso in cui enumeriamo le barre che partecipano alla regressione da 1 a N in modo ascendente dal passato al futuro:

Eng_m2

Il modo per enumerare convenzionalmente le barre per la regressione per utilizzare l'indicatore LWMA 

 

Pertanto, la stessa enumerazione deve essere utilizzata in tutte le altre equazioni.

Procediamo con il metodo:

  • x totale non è altro che (1 + 2 + ... + N) numero totale di serie che può essere sostituito con la seguente equazione:

  • x*x totale è semplificato secondo un'altra equazione:

  • per costruire un grafico indicatore dobbiamo calcolare il significato della funzione di regressione solo per la sua ultima barra in cui x è uguale a N.I.e., l'equazione della funzione di regressione può essere sostituita con il suo caso particolare:


Pertanto, le ultime cinque equazioni ci consentono di ottenere sostituzioni per tutte le variabili nelle equazioni di calcolo dei rapporti a e b e nell'equazione di regressione stessa. Dopo aver completato tutte queste sostituzioni, otterremo una nuova equazione per il calcolo del valore di regressione. Consisterà solo dei valori degli indicatori della Media Mobile e della cifra N. Dopo tutte le riduzioni dei suoi elementi otterremo un'elegante equazione:

Questa equazione sostituisce tutti i calcoli eseguiti nell'indicatore di base della regressione lineare. È abbastanza evidente che il codice dell'indicatore con quell'equazione sarà molto più efficiente in termini di spazio. Nel capitolo "Confronto velocità" scopriremo anche se il codice funziona più velocemente.

Parte specificata dell'indicatore:

            double SMA [1];
            double LWMA[1];
            CopyBuffer(h_SMA,  0, rates_total-bar, 1, SMA);            
            CopyBuffer(h_LWMA, 0, rates_total-bar, 1, LWMA);

            lrvalue = 3*LWMA[0] - 2*SMA[0];

Gli indicatori LWMA e SMA (Media Mobile Semplice) sono creati preliminarmente su OnInit:

      h_SMA  = iMA(NULL, 0, LRPeriod, 0, MODE_SMA,  PRICE_CLOSE);
      h_LWMA = iMA(NULL, 0, LRPeriod, 0, MODE_LWMA, PRICE_CLOSE);

Il codice completo è allegato all'articolo. Il metodo di calcolo "Semplificazione" deve essere impostato nelle impostazioni dell'indicatore.

Si noti che in questo metodo abbiamo utilizzato gli indicatori incorporati nel terminale, ovvero è stata utilizzata la funzione iMA con la selezione dei metodi di livellamento appropriati invece di iCustom. È una cosa importante perché in teoria gli indicatori integrati dovrebbero funzionare molto velocemente. Alcuni altri indicatori standard sono integrati nel terminale (sono creati da funzioni con prefisso "i" come iMA). Durante l'utilizzo del metodo di semplificazione, è molto meglio semplificare le equazioni per questi indicatori.


Il terzo metodo. Approssimazione

L'idea di questo metodo è che gli indicatori "pesanti" utilizzati in un expert possano essere sostituiti con quelli molto più veloci che calcolano approssimativamente i valori necessari. Usando questo metodo puoi testare la tua strategia più velocemente. Dopotutto, l'accuratezza della previsione non è così importante nella fase di debug.

Inoltre, questo metodo può essere utilizzato con una strategia di lavoro per ottimizzare approssimativamente i parametri. Ciò consente di trovare rapidamente le aree dei valori effettivi dei parametri. E poi possono essere elaborati da indicatori "pesanti" per la regolazione fine.

Inoltre, può sembrare che un calcolo approssimativo sia sufficiente per consentire a una strategia di funzionare correttamente. In tal caso un indicatore "lightened" può essere utilizzato anche nel trading reale.

Un'equazione veloce può essere sviluppata per la regressione lineare che ha un effetto simile alla regressione. Ad esempio, possiamo dividere le barre di regressione in due gruppi, calcolare il valore medio per ciascuno di essi, tracciare una linea attraverso quei due punti medi e definire il valore della linea nell'ultima barra:

Eng_Points

I punti sono stati divisi in due gruppi - quello sinistro e quello destro - e sono stati eseguiti i calcoli

 

Questo calcolo contiene meno operazioni aritmetiche rispetto al caso di regressione. Questo è il modo per accelerare i calcoli.

           // The interval midpoint
           int HalfPeriod = (int) MathRound(LRPeriod/2);
           
           // Average price of the first half
           double s1 = 0;
           for (int i = 0; i < HalfPeriod; i++)
              s1 += price[bar-i];
           s1 /= HalfPeriod;
              
           // Average price of the second half
           double s2 = 0;
           for (int i = HalfPeriod; i < LRPeriod; i++)
              s2 += price[bar-i];
           s2 /= (LRPeriod-HalfPeriod);
           
           // Price excess by one bar
           double k = (s1-s2)/(LRPeriod/2);
           
           // Extrapolated price at the last bar
           lrvalue = s1 + k * (HalfPeriod-1)/2;

Il codice completo dell'indicatore è allegato all'articolo. Il metodo di calcolo "approssimativo" deve essere impostato nelle impostazioni dell'indicatore.

Ora, analizziamo quanto questo si avvicina all'originale. Per raggiungere questo obiettivo dobbiamo impostare indicatori con metodi di calcolo standard e approssimativi su un grafico. Dobbiamo anche aggiungere qualsiasi altro indicatore che sia consapevolmente e debolmente simile alla regressione. Tuttavia, deve anche calcolare alcuni trend utilizzando le barre passate. La media mobile andrà bene per questo (ho usato LWMA, non SMA - è molto più simile al grafico di regressione). A parte questo possiamo valutare se abbiamo una buona approssimazione o meno. Secondo me va bene:

Eng_G3

 La linea rossa è più vicina a quella blu che a quella verde. Significa che l'algoritmo di approssimazione è buono


Confronto di velocità

La visualizzazione del registro può essere attivata nei parametri dell'indicatore:

Eng_True

Impostazione dell'indicatore per la valutazione di una velocità di esecuzione

 

In questo caso, l'indicatore visualizzerà tutti i dati necessari per la valutazione della velocità in experts messages log: l'ora dell'inizio dell'elaborazione dell'evento OnInit() e la fine di SuCalcola(). Spiegherò perché la velocità deve essere valutata da questi due valori. L'agente OnInit() viene eseguito quasi istantaneamente in caso di qualsiasi metodo e OnCalculate() si avvia subito dopo OnInit() in caso di quasi tutti i metodi. L'unica eccezione è un metodo di semplificazione in cui gli indicatori SMA e LWMA vengono creati su OnInit(). È presente un ritardo tra la fine di OnInit() e l'inizio di OnCalculate() nel caso (e solo in quel caso!) del metodo menzionato:

Eng_log

Registro di esecuzione visualizzato dall'indicatore nel journal degli expert del terminale 

 

Significa che questo ritardo è causato dalla SMA e dalla LWMA appena create che stavano eseguendo alcuni calcoli in quel momento. Anche la durata di questi calcoli deve essere considerata, quindi valuteremo tutto il tempo "ininterrottamente" - dall'inizializzazione dell'indicatore di regressione fino alla fine dei suoi calcoli.

Per notare la differenza tra le velocità dei diversi metodi in modo più accurato, tutte le valutazioni vengono condotte utilizzando un enorme array di dati - intervallo di tempo M1 con profondità della cronologia massima accessibile. Sono più di 4 milioni di barre. Ciascun metodo sarà valutato due volte: con 20 e 2000 barre in regressione.

I risultati sono i seguenti:

Eng_Duration 1

Eng_Duration 2
 

Come puoi vedere, tutti e tre i metodi di ottimizzazione hanno mostrato un aumento della velocità di almeno due volte rispetto al metodo di calcolo della regressione standard. Dopo l'aumento del numero di barre nella regressione, i totali mobili ei metodi di semplificazione hanno mostrato una velocità fantastica. Hanno lavorato centinaia di volte più velocemente di uno standard!

Devo farvi notare che il tempo necessario per il calcolo con questi due metodi è rimasto praticamente invariato. Questo fatto può essere facilmente spiegato: non importa quante barre sono state utilizzate per creare una regressione, nel metodo dei totali mobili vengono eseguite solo 2 azioni, una vecchia barra esce e ne entra una nuova. Non ci sono cicli che dipendono dalla lunghezza della regressione. Pertanto, anche se la regressione contiene 20000 o 200000 barre, il tempo di esecuzione del metodo aumenterà in modo insignificante rispetto a 20 barre.

Il metodo di semplificazione utilizza la Media Mobile in diverse modalità nella sua equazione. Come ho già notato, questo indicatore può essere facilmente ottimizzato con il metodo dei totali mobili ed è utilizzato dagli sviluppatori del terminale. Non c'è da meravigliarsi se anche il tempo di esecuzione del metodo di semplificazione non cambia nel caso in cui la lunghezza della regressione venga aumentata.

Il metodo dei totali mobili si è rivelato il metodo di calcolo più veloce nel nostro esperimento.

 

Conclusione

Alcuni trader stanno seduti ad aspettare la fine di un'altra procedura di ottimizzazione dei parametri dei loro sistemi di trading nei loro tester. Ma ci sono anche alcuni trader che fanno trading e guadagnano già in quel preciso momento. Le velocità di calcolo ottenute con i metodi descritti spiegano chiaramente perché esiste una tale differenza tra questi gruppi di trader. E perché è così importante prestare attenzione alla qualità degli algoritmi di trading.

Non importa se scrivi tu stesso i programmi per il terminale o li ordini a programmatori di terze parti (ad esempio, con l'aiuto della sezione "Lavori"). In ogni caso, puoi ottenere non solo indicatori e strategie funzionanti, ma anche veloci nel caso tu sia pronto a fare qualche sforzo per spendere dei soldi.

Se utilizzi qualsiasi metodo di accelerazione degli algoritmi, ottieni un vantaggio in termini di velocità da decine a centinaia di volte rispetto agli algoritmi standard. Significa che puoi, ad esempio, ottimizzare i parametri delle tue strategie di trading in un tester cento volte più velocemente. E farlo con più attenzione e frequenza. Inutile dire che ciò si traduce in un aumento dei tuoi guadagni di trading.


Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/270

File allegati |
Distribuzioni statistiche di probabilità in MQL5 Distribuzioni statistiche di probabilità in MQL5
L'articolo affronta le distribuzioni di probabilità (normale, log-normale, binomiale, logistica, esponenziale, distribuzione di Cauchy, distribuzione t di Student, distribuzione di Laplace, distribuzione di Poisson, distribuzione iperbolica delle secanti, distribuzione Beta e Gamma) delle variabili casuali utilizzate nella statistica applicata. Dispone anche di classi per la gestione di queste distribuzioni.
Filtraggio dei segnali basati su dati statistici di correlazione dei prezzi Filtraggio dei segnali basati su dati statistici di correlazione dei prezzi
Esiste una correlazione tra il comportamento dei prezzi passati e le sue tendenze future? Perché il prezzo ripete oggi il carattere del suo movimento del giorno precedente? Le statistiche possono essere utilizzate per prevedere le dinamiche dei prezzi? C'è una risposta ed è positiva. Se hai qualche dubbio, allora questo articolo fa al caso tuo. Ti spiegherò come creare un filtro funzionante per un sistema di trading con MQL5, rivelando un modello interessante nelle variazioni di prezzo.
Tracciamento, debug e analisi strutturale del codice sorgente Tracciamento, debug e analisi strutturale del codice sorgente
L'intero complesso di problemi relativi alla creazione di una struttura di un codice eseguito e al suo tracciamento può essere risolto senza serie difficoltà. Questa possibilità è apparsa su MetaTrader 5 grazie alla nuova funzionalità del linguaggio MQL5: creazione automatica di variabili di tipo complesso di dati (strutture e classi) e loro eliminazione quando si esce dall'ambito locale. L'articolo contiene la descrizione della metodologia e dello strumento già pronto.
Il ruolo delle distribuzioni statistiche nel lavoro del trader Il ruolo delle distribuzioni statistiche nel lavoro del trader
Questo articolo è una continuazione logica del mio articolo Statistical Probability Distributions in MQL5 che espone le classi per lavorare con alcune distribuzioni statistiche teoriche. Ora che abbiamo una base teorica, suggerisco di procedere direttamente a set di dati reali e provare a fare un uso informativo di questa base.