Consulenti sulle reti neurali, condividendo le esperienze. - pagina 9

 
Andrey Emelyanov:

Ho anche cercato di implementare un algoritmo simile nel 2013... Ma ho usato 7 indicatori, e Zigzag è stato utilizzato per formare un vettore per la formazione del NS. Ma l'essenza è la stessa - stavo cercando posizioni inverse... Quando ho iniziato a usare Zigzag non ho avuto fortuna con i dati degli indicatori e i segnali di trading. finché non mi sono imbattuto per caso in alcuni modelli. Questo ha cambiato radicalmente il mio TS. Ora il mio algoritmo è molto più semplice:

1. Calcolo dei modelli su minuti e ore, nell'ultimo anno;

2. Fare un dizionario dei punti di svolta (coppie "modello minuto - modello ora") ;

3. insegnare NS utilizzando il dizionario dei punti di ribaltamento (su 150-160 coppie);

Questo è il risultato del mio approccio:

Agli svantaggi del mio approccio:

1) Alto rischio del TS - poiché non è possibile determinare il valore esatto del prezzo di rottura, il TS piazza 9 ordini pendenti con lotti: 1, 1, 3, 6, 14, 31, 70, 158, 355;

2) Difficile implementare un algoritmo di uscita (TS a strascico);

Quindi NS può essere usato per il trading, l'unica domanda è cosa insegnare a NS...

P/s: Per modelli intendo i modelli di A. Merrill (M & W).

È un approccio intelligente. E i modelli sono stati descritti semplicemente come la posizione delle barre nella matrice, senza prendere in considerazione il delta del prezzo reale - solo la posizione relativa?

Ho un'idea, provare gli indicatori di pattern ma con un frame diverso - le prime cinque barre analizziamo gli indicatori sugli ultimi 5 indicatori, e i due indicatori per l'analisi della tendenza - analizziamo in incrementi di 10 e prendiamo in considerazione i cambiamenti assoluti.

Lo zig-zag è un'idea intelligente, ma come filtrano i picchi dalle oscillazioni piatte che potrebbero essere falsi punti di cambiamento di tendenza?

 
-Aleks-:

Un approccio sensato. E i modelli descritti semplicemente come la posizione delle barre nella matrice, senza prendere in considerazione il delta del prezzo reale - solo la posizione relativa?

Ho un'idea, provare gli indicatori di pattern, ma con un frame diverso - le prime cinque barre analizziamo gli indicatori sugli ultimi 5 indicatori, e due indicatori per l'analisi della tendenza - analizziamo a passi di 10 e allo stesso tempo prendiamo in considerazione i cambiamenti assoluti.

Riguardo allo zig-zag è un'idea intelligente, ma come i picchi filtrati dalle oscillazioni piatte potrebbero essere falsi punti di cambiamento di tendenza?

Io lo faccio in questo modo:

C'è un array dinamico che memorizza esclusivamente coppie di pattern (lo chiamo dizionario), se una coppia di pattern entra nel dizionario una seconda volta non la scrivo; e due array di contatori di senior timeframe e junior - contano quanto spesso un pattern è stato coinvolto nella formazione di coppie, anche se non è stato scritto nel dizionario.

Il vettore di formazione è formato secondo il dizionario, il peso di un pattern individuale = pattern_counter / maximum_counter. Cioè, il modello che partecipa più spesso alla formazione di coppie è uguale a 1, e tutti gli altri modelli sono inferiori a 1. Questa è la tabella che si ottiene dopo aver insegnato al NS:

Modello principale Conteggio principale Modello slave Conteggio degli schiavi Somma_Multilayer_Perceptron
W2 18 W2 21 0.94914702
W14 14 W2 21 0.84972197
M15 20 M15 14 0.83269191
W1 11 W2 21 0.77499075
W13 10 W2 21 0.75006553
M15 20 M3 10 0.73813147
M15 20 M10 10 0.73812512
M15 20 M16 10 0.738099
W5 9 W2 21 0.72506739
W10 9 W2 21 0.72505412
M15 20 M11 9 0.71431236
W2 18 W1 11 0.71204136
W2 18 W5 11 0.7118911
W4 8 W2 21 0.70017271
W2 18 W4 10 0.68815217
W2 18 W7 10 0.68802818
M15 20 M7 7 0.66682395
M15 20 M14 6 0.64291215
W2 18 W13 8 0.64045346
M3 12 M15 14 0.63254238
W9 5 W2 21 0.62522345
W3 5 W2 21 0.62509623
W7 5 W2 21 0.62505511
M15 20 M12 5 0.61917222
M15 20 M8 5 0.6191331
W14 14 W1 11 0.61210667
W6 4 W2 21 0.60012943
W2 18 W14 6 0.59301682

Struttura del NS: 64 neuroni di ingresso, 4 interni, 1 uscita. Cioè, un neurone di ingresso descrive un modello. La griglia impiega 40-50 minuti per allenarsi, e l'errore di NS non supera lo 0,00001.

Così ho un modello che può predire il significato delle coppie di modelli, anche se prima non era nel dizionario.

Ho lottato a lungo con i picchi piatti e falsi, ma sto calcolando ZigZaga. Ho leggermente modificato il codice di uno Zigzag standard, cioè ho implementato la percentuale ZZ sulla sua base. Finora, il codice sembra più o meno il seguente:

int MyCExtremum::GetCombiZigzag(const double    &high[],     // буфер цен high

                                const double    &low[],      // буфер цен low

                                const datetime  &time[],     // буфер время 

                                int             ExtDepth,    // глубина поиска экстремумов(первого прохода)

                                double          ExtDeviation,// "пороговое значение": жесткая ступенька + % роста цены

                                int             ExtBackstep  // глубина поиска экстремумов(второго прохода)

                               )

  {

   //--- value

   int    shift=0, whatlookfor=0, lasthighpos=0, lastlowpos=0, Deviat=1;

   double lasthigh=0.0, lastlow=0.0, percent=0.0;

   int    rates_total = ArraySize(time);          // размер входных таймсерий

   int    limit       = rates_total - ExtDepth;   // лимит на расчеты...

   //+---------------------------------------------------------------+

   //| ОЧЕНЬ ВАЖНАЯ ПРОВЕРКА ВЛИЯЮЩАЯ НА КОРРЕКТНОСТЬ ВЫЧИСЛЕНИЙ!    |

   //+---------------------------------------------------------------+

   if(ArrayIsSeries(high)) ArraySetAsSeries(high,false);

   if(ArrayIsSeries(low))  ArraySetAsSeries(low,false);

   if(ArrayIsSeries(time)) ArraySetAsSeries(time,false);

   //+---------------------------------------------------------------+

   //| ПРОВЕРКИ ВХОДНЫХ ПЕРЕМЕННЫХ                                   |

   //+---------------------------------------------------------------+

   if(rates_total<20)

     { 

      Print(__FUNCTION__," ERROR: the small size of the buffer.");

      return(-1);                                     

     }

   if(ExtDeviation<0 || ExtDeviation>100)

     { 

      Print(__FUNCTION__," ERROR: Is\'not correct a Deviation. The value of Deviation should be in the interval [0..100].");

      return(-1);                                     

     }

   //--- Проверка: Depth and Backstep

   if((ExtDepth < ExtBackstep)||(ExtDepth < 2))

     {

      Print(__FUNCTION__+" ERROR: Is\'not correct a Depth and Backstep. The value of Depth should be greater than Backstep.");

      return(-1);

     }

   //--- готовим буфер ZigzagBuffer[]

   if(ArraySize(ZigzagBuffer)>0) ArrayFree(ZigzagBuffer);               // Удаляем старые данные

   ArrayResize(ZigzagBuffer,rates_total, EXTREMUM_RESERVE);

   ArrayFill(ZigzagBuffer,0,rates_total,0.0);

   if(ArrayIsSeries(ZigzagBuffer))  ArraySetAsSeries(ZigzagBuffer,  false);

   //---

   if(ArraySize(HighMapBuffer)>0) ArrayFree(HighMapBuffer);             // Удаляем старые данные

   ArrayResize(HighMapBuffer,rates_total, EXTREMUM_RESERVE);

   ArrayFill(HighMapBuffer,0,rates_total,0.0);

   if(ArrayIsSeries(HighMapBuffer)) ArraySetAsSeries(HighMapBuffer, false);

   //---

   if(ArraySize(LowMapBuffer)>0) ArrayFree(LowMapBuffer);               // Удаляем старые данные

   ArrayResize(LowMapBuffer,rates_total, EXTREMUM_RESERVE);

   ArrayFill(LowMapBuffer,0,rates_total,0.0);

   if(ArrayIsSeries(LowMapBuffer))  ArraySetAsSeries(LowMapBuffer,  false);   

   //---

   if(ArraySize(TimeBuffer)>0) ArrayFree(TimeBuffer);                   // Удаляем старые данные

   ArrayResize(TimeBuffer,     rates_total, EXTREMUM_RESERVE);

   ArrayFill(TimeBuffer,    0, rates_total,   0);

   if(ArrayIsSeries(TimeBuffer))  ArraySetAsSeries(TimeBuffer,  false);   

   //--- корректировка Deviation

   if(ExtDeviation < 1)

     {

      Deviat = 1;

     }else

        {

         Deviat = (int)ExtDeviation;

        }

   //--- получаем "свежие" минимумы и максимумы

   if(GetHighMapZigzag(high,ExtDepth,Deviat,ExtBackstep) < 0) return(0);

   if(GetLowMapZigzag(low,ExtDepth,Deviat,ExtBackstep)   < 0) return(0);

   //--- final rejection

   for(shift=ExtDepth;shift<rates_total;shift++)

     {

      switch(whatlookfor)

        {

         case Start: // search for peak or lawn

            if(lastlow==0 && lasthigh==0)

              {

               if(HighMapBuffer[shift]!=0)

                 {

                  lasthigh=high[shift];

                  lasthighpos=shift;

                  whatlookfor=Sill;

                  ZigzagBuffer[shift]=lasthigh;

                  TimeBuffer[shift]=time[shift];

                 }

               if(LowMapBuffer[shift]!=0)

                 {

                  lastlow=low[shift];

                  lastlowpos=shift;

                  whatlookfor=Pike;

                  ZigzagBuffer[shift]=lastlow;

                  TimeBuffer[shift]=time[shift];

                 }

              }

            break;

         case Pike: // search for peak

            if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)

              {

               //---

               ZigzagBuffer[lastlowpos] = 0.0;

               TimeBuffer[lastlowpos]   = 0;

               //---

               lastlowpos=shift;

               lastlow=LowMapBuffer[shift];

               ZigzagBuffer[shift]=lastlow;

               TimeBuffer[shift]=time[shift];

               //--- Обязательно: покинуть switch

               break;

              }

            //--- Обход "двойственности"

            if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow)

              {

               //---

               ZigzagBuffer[lastlowpos] = 0.0;

               TimeBuffer[lastlowpos]   = 0;

               //---

               lastlowpos=shift;

               lastlow=LowMapBuffer[shift];

               ZigzagBuffer[shift]=lastlow;

               TimeBuffer[shift]=time[shift];

               //--- Обязательно: покинуть switch

               break;

              }

            if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)

              {

               //--- Проверка: % роста цены

               percent = (HighMapBuffer[shift]-lastlow)/(lastlow/100);

               if(percent > ExtDeviation)

                 {

                  lasthigh=HighMapBuffer[shift];

                  lasthighpos=shift;

                  ZigzagBuffer[shift]=lasthigh;

                  TimeBuffer[shift]=time[shift];

                  whatlookfor=Sill;

                 }

               percent = 0.0;

              }            

            break;

         case Sill: // search for lawn

            if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)

              {

               //--- 

               ZigzagBuffer[lasthighpos] = 0.0;

               TimeBuffer[lasthighpos]   = 0;

               //---

               lasthighpos=shift;

               lasthigh=HighMapBuffer[shift];

               ZigzagBuffer[shift]=lasthigh;

               TimeBuffer[shift]=time[shift];

               //--- Обязательно: покинуть switch

               break;

              }

            if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh)

              {

               //--- 

               ZigzagBuffer[lasthighpos] = 0.0;

               TimeBuffer[lasthighpos]   = 0;

               //---

               lasthighpos=shift;

               lasthigh=HighMapBuffer[shift];

               ZigzagBuffer[shift]=lasthigh;

               TimeBuffer[shift]=time[shift];

               //--- Обязательно: покинуть switch

               break;

              }

            if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)

              {

               //--- Проверка: % роста цены

               percent = (lasthigh-LowMapBuffer[shift])/(lasthigh/100);

               if(percent > ExtDeviation)

                 {

                  lastlow=LowMapBuffer[shift];

                  lastlowpos=shift;

                  ZigzagBuffer[shift]=lastlow;

                  TimeBuffer[shift]=time[shift];

                  whatlookfor=Pike;                  

                 }

               percent = 0.0;

              }

            break;

         default: 

            return(-1);

        }

     }

   //--- return value of prev_calculated for next call

   return(rates_total);   

  }

MyCExtremum è una classe per il calcolo di ZigZag...

File:
MyCExtremum.mqh  37 kb
 
-Aleks-:

Un approccio sensato. E i modelli descritti semplicemente come la posizione delle barre nella matrice, senza prendere in considerazione il delta del prezzo reale - solo la posizione relativa?

Ho un'idea, provare gli indicatori di pattern, ma con un frame diverso - le prime cinque barre analizziamo gli indicatori sugli ultimi 5 indicatori, e due indicatori per l'analisi della tendenza - analizziamo a passi di 10 e allo stesso tempo prendiamo in considerazione i cambiamenti assoluti.

Lo zig-zag è un'idea intelligente, ma come filtrano i picchi dalle oscillazioni piatte che potrebbero essere falsi punti di cambiamento di tendenza?

Riguardo all'analisi degli indicatori usando i pattern - questo è molto interessante... Penso che ci sia meno rumore sugli indicatori, ma dovremmo scegliere gli indicatori in modo che alcuni sopprimano il "basso rumore" e altri "l'alto rumore", quindi si ottiene un multifiltro.
 

Andrey Emelyanov:

Struttura del NS: 64 neuroni di ingresso, 4 interni, 1 uscita. Cioè, un neurone di ingresso descrive un modello.

Spera di ottenere dei risultati con questo modello? Il tuo strato interno agisce come un compressore intermedio, non come un classificatore.
 
Andrey Emelyanov:

Faccio quanto segue:

C'è un array dinamico che memorizza esclusivamente coppie di pattern (lo chiamo il dizionario), se una coppia di pattern è entrata nel dizionario una seconda volta non la scrivo; e due array di contatori di timeframe alti e bassi - contano quanto spesso un pattern è stato coinvolto nella formazione di coppie, anche se non è stato scritto nel dizionario.

Il vettore di formazione è formato secondo il dizionario, il peso di un pattern individuale = pattern_counter / maximum_counter. Cioè, il modello che partecipa più spesso alla formazione di coppie è uguale a 1, e tutti gli altri modelli sono inferiori a 1. Questa è la tabella che si ottiene dopo aver insegnato al NS:

Modello principale Conteggio principale Modello slave Conteggio degli schiavi Somma_Multilayer_Perceptron
W2 18 W2 21 0.94914702
W14 14 W2 21 0.84972197
M15 20 M15 14 0.83269191
W1 11 W2 21 0.77499075
W13 10 W2 21 0.75006553
M15 20 M3 10 0.73813147
M15 20 M10 10 0.73812512
M15 20 M16 10 0.738099
W5 9 W2 21 0.72506739
W10 9 W2 21 0.72505412
M15 20 M11 9 0.71431236
W2 18 W1 11 0.71204136
W2 18 W5 11 0.7118911
W4 8 W2 21 0.70017271
W2 18 W4 10 0.68815217
W2 18 W7 10 0.68802818
M15 20 M7 7 0.66682395
M15 20 M14 6 0.64291215
W2 18 W13 8 0.64045346
M3 12 M15 14 0.63254238
W9 5 W2 21 0.62522345
W3 5 W2 21 0.62509623
W7 5 W2 21 0.62505511
M15 20 M12 5 0.61917222
M15 20 M8 5 0.6191331
W14 14 W1 11 0.61210667
W6 4 W2 21 0.60012943
W2 18 W14 6 0.59301682

Struttura del NS: 64 neuroni di ingresso, 4 interni, 1 uscita. Cioè, un neurone di ingresso descrive un modello. La griglia impiega 40-50 minuti per allenarsi, e l'errore di NS non supera lo 0,00001.

Così ho un modello che può predire il significato delle coppie di modelli, anche se prima non era nel dizionario.

Ho lottato a lungo con i picchi piatti e falsi, ma sto calcolando ZigZaga. Ho leggermente modificato il codice di uno Zigzag standard, cioè ho implementato la percentuale ZZ sulla sua base. Finora, il codice sembra più o meno il seguente:

L'array è una soluzione interessante. Ci sono differenze nelle statistiche tra coppie/periodi, qual è la stabilità in generale della variabilità della frequenza di occorrenza di un modello che dà un risultato di predizione positivo?

Riguardo allo zig-zag, ho anche una soluzione percentuale, ma uso anche una storia più profonda per calcolare una sezione di riferimento dello zig-zag, rispetto alla quale confronto il cambiamento percentuale negli altri.

 
Andrey Emelyanov:
Per quanto riguarda l'analisi degli indicatori con i modelli - questo è molto interessante... Penso che ci sia meno rumore negli indicatori, ma devi scegliere gli indicatori in modo che uno sopprima il "basso rumore" e l'altro "l'alto rumore", quindi hai un multi-filtro.
Ci sono molti indicatori diversi. Ho sperimentato con oscillatori standard (e il loro tipo di senza interessi), e sono riuscito a fare profitto su tutti loro - tutto dipende dalle impostazioni... è solo una questione di casualità o di regolarità.
 
Комбинатор:
Spera di ottenere dei risultati con questo modello? Il tuo strato interno agisce come un compressore intermedio, non come un classificatore.
Questa è la compressione di cui ho bisogno... ad un certo punto (sulla barra corrente) su 64 ingressi solo 2 ingressi sono non-zero... e il compito della rete non è quello di dividere per comprare/vendere, ma di misurare qual è la probabilità di un rimbalzo a dati input. O sto ragionando male?
 
-Aleks-:

L'array è una soluzione interessante. C'è qualche differenza nelle statistiche tra coppie/periodi, qual è la stabilità in generale della variabilità di frequenza del verificarsi del modello che dà un risultato di previsione positivo?

Riguardo allo zig-zag, ho anche una soluzione percentuale, ma uso anche una storia più profonda per calcolare una sezione di riferimento dello zig-zag, rispetto alla quale confronto il cambiamento percentuale negli altri.

Come tutti sanno, i modelli di A. Merrill non danno una risposta esatta se il modello si svilupperà ulteriormente (mantenere la tendenza) o cambiare in un altro modello (rimbalzo del prezzo). Ecco perché ho deciso di cercare la risposta usando due intervalli di tempo - un'ora e un minuto. Sto raccogliendo statistiche di ricorrenza delle coppie e non ho ancora un dizionario di formazione universale. Tuttavia sono sicuro che questa connessione deve esistere... Altrimenti non ci sarebbero modelli armoniosi: farfalle, pipistrelli, ecc.
 
Andrey Emelyanov:
Come tutti sanno, i modelli di A. Merrill non danno una risposta esatta se il modello si svilupperà ulteriormente (mantenere la tendenza) o cambiare in un altro modello (rimbalzo del prezzo). Ecco perché ho deciso di cercare la risposta usando due intervalli di tempo - un'ora e un minuto. Sto raccogliendo statistiche di ricorrenza delle coppie e non ho ancora un dizionario di formazione universale. Tuttavia sono sicuro che questa connessione deve esistere... Altrimenti non ci sarebbero modelli armoniosi: farfalle, pipistrelli, ecc.
I modelli percepiti visivamente da un uomo come "farfalle, pipistrelli, ecc." nascono solo nel cervello umano e, come penso, è necessario considerare questo fattore, è necessario studiare la psicologia cognitiva su questo argomento per capire cosa è essenziale per il cervello e cosa no nella percezione del modello, cioè quali errori sono accettabili e quali no. Il cervello spesso completa ciò che si aspetta di vedere - il suo vocabolario di modelli è limitato, quindi mette combinazioni simili di candele in un'unica immagine, cioè non usa il modello matematico esatto per descrivere ciò che vede.
 

Il mio bambino è ancora muto e ottuso, ma sta facendo progressi... 8 indicatori di ingresso, 1 uscita, 15 neuroni nello strato coperto. 2000 vettore di input, 10000 epoche di allenamento.

Questo è in realtà il 3° o 4°, ottenendo tutti più o meno gli stessi risultati. Credo di aver bisogno di più neuroni e di un vettore di input, ma ci vuole molto tempo per allenarsi.

Ho un'idea approssimativa del modello che dovrebbe raccogliere, ho selezionato indicatori da diversi timeframe e gli output sembrano avere informazioni significative.