Asesores en redes neuronales, compartiendo experiencias. - página 9

 
Andrey Emelyanov:

También intenté implementar un algoritmo similar allá por 2013.... Pero utilicé 7 indicadores, y Zigzag se utilizó para formar un vector para el entrenamiento del NS. Pero la esencia es la misma: buscaba posiciones inversas... Cuando empecé a utilizar Zigzag no tenía ni idea de qué hacer con él. hasta que accidentalmente me encontré con algunos patrones. Eso cambió radicalmente mi ST. Ahora mi algoritmo es mucho más sencillo:

1. Cálculo de patrones en el marco de minutos y horas, durante el último año;

2. Hacer un diccionario de puntos de inflexión (pares "patrón de minutos - patrón de horas") ;

3. Enseñar NS utilizando el diccionario de puntos de inflexión (sobre 150-160 pares);

Este es el resultado de mi enfoque:

A las desventajas de mi enfoque:

1) Alto riesgo de la ST - como no es posible determinar el valor exacto del precio de ruptura, la ST coloca 9 órdenes pendientes con lotes: 1, 1, 3, 6, 14, 31, 70, 158, 355;

2) Dificultad para implementar un algoritmo de salida (TS de arrastre);

Así que la NS puede utilizarse para el comercio, la única cuestión es qué enseñar a la NS...

P/s: Por patrones entiendo los de A. Merrill (M & W) .

Es un enfoque inteligente. ¿Y los patrones se describieron simplemente como la posición de las barras en la matriz, sin tener en cuenta el delta del precio real, sólo la posición relativa?

Tengo una idea, probar los indicadores de patrón pero con un marco diferente - las primeras cinco barras analizamos los indicadores en los últimos 5 indicadores, y los dos indicadores para el análisis de la tendencia - analizamos en incrementos de 10 y tenemos en cuenta los cambios absolutos.

El zig-zag es una idea inteligente, pero ¿cómo se filtran los picos de los bamboleos planos que podrían ser falsos puntos de cambio de tendencia?

 
-Aleks-:

Un enfoque sensato. ¿Y los patrones descritos simplemente como la posición de las barras en la matriz, sin tener en cuenta el delta del precio real - sólo la posición relativa?

Tengo una idea, probar los indicadores de patrones, pero con un marco diferente - las primeras cinco barras analizamos los indicadores en los últimos 5 indicadores, y dos indicadores para el análisis de la tendencia - analizamos en pasos de 10 y al mismo tiempo tener en cuenta los cambios absolutos.

Lo del zig-zag es una idea inteligente, pero ¿cómo los picos filtrados de los bamboleos planos podrían ser falsos puntos de cambio de tendencia?

Yo lo hago así:

Hay un array dinámico que almacena exclusivamente pares de patrones (lo llamo diccionario), si un par de patrones entra en el diccionario por segunda vez no lo escribo; y dos arrays contadores de tiempo mayor y menor - cuentan cuántas veces un patrón estuvo involucrado en la formación de pares, incluso si no fue escrito en el diccionario.

El vector de entrenamiento se forma según el diccionario, el peso de un patrón individual = contador_de_patrón / contador_máximo. Es decir, el patrón que participa en la formación de parejas con mayor frecuencia es igual a 1, y todos los demás patrones son menores que 1. Esta es la tabla que se obtiene después de enseñar el NS:

Patrón principal Recuento principal Patrón esclavo Recuento de esclavos Suma_Multicapa_Perceptrón
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

Estructura del NS: 64 neuronas de entrada, 4 internas, 1 de salida. Es decir, una neurona de entrada describe un patrón. La cuadrícula tarda entre 40 y 50 minutos en entrenarse, y el error de NS no supera el 0,00001.

De este modo, tengo un modelo que puede predecir el significado de los pares de patrones, incluso si antes no estaba en el diccionario.

Llevo mucho tiempo luchando con los picos planos y falsos, pero estoy trabajando en el nivel de cálculo de ZigZaga. He modificado ligeramente el código de un Zigzag estándar, es decir, implementado el porcentaje ZZ en su base. Hasta ahora, el código se ve más o menos como sigue:

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 es una clase para calcular el ZigZag...

Archivos adjuntos:
MyCExtremum.mqh  37 kb
 
-Aleks-:

Un enfoque sensato. ¿Y los patrones descritos simplemente como la posición de las barras en la matriz, sin tener en cuenta el delta del precio real - sólo la posición relativa?

Tengo una idea, probar los patrones de los indicadores, pero con un marco diferente - las primeras cinco barras analizamos los indicadores en los últimos 5 indicadores, y dos indicadores para el análisis de la tendencia - analizamos en incrementos de 10 y al mismo tiempo tener en cuenta los cambios absolutos.

El zig-zag es una idea inteligente, pero ¿cómo se filtran los picos de los bamboleos planos que podrían ser falsos puntos de cambio de tendencia?

Sobre el análisis de los indicadores mediante patrones - es muy interesante... Creo que hay menos ruido en los indicadores, pero deberíamos elegir los indicadores de forma que unos supriman el "bajo ruido" y otros el "alto ruido", entonces se consigue un multifiltro.
 

Andrey Emelyanov:

Estructura del NS: 64 neuronas de entrada, 4 internas, 1 de salida. Es decir, una neurona de entrada describe un patrón.

¿Espera resultados con este modelo? Su capa interna actúa como un compresor intermedio, no como un clasificador.
 
Andrey Emelyanov:

Hago lo siguiente:

Hay un array dinámico que almacena exclusivamente pares de patrones (lo llamo el diccionario), si un par de patrones entró en el diccionario por segunda vez no lo escribo; y dos arrays de contador de tiempo alto y de tiempo bajo - cuentan cuántas veces un patrón estuvo involucrado en la formación de pares, incluso si no fue escrito en el diccionario.

El vector de entrenamiento se forma según el diccionario, el peso de un patrón individual = contador_de_patrón / contador_máximo. Es decir, el patrón que participa en la formación de parejas con mayor frecuencia es igual a 1, y todos los demás patrones son menores que 1. Esta es la tabla que se obtiene después de enseñar el NS:

Patrón principal Recuento principal Patrón esclavo Recuento de esclavos Suma_Multicapa_Perceptrón
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

Estructura del NS: 64 neuronas de entrada, 4 internas, 1 de salida. Es decir, una neurona de entrada describe un patrón. La cuadrícula tarda entre 40 y 50 minutos en entrenarse, y el error de NS no supera el 0,00001.

De este modo, tengo un modelo que puede predecir el significado de los pares de patrones, incluso si antes no estaba en el diccionario.

Llevo mucho tiempo luchando con los picos planos y falsos, pero estoy trabajando en el nivel de cálculo de ZigZaga. He modificado ligeramente el código de un Zigzag estándar, es decir, implementado el porcentaje ZZ en su base. Hasta ahora, el código se ve más o menos como sigue:

La matriz es una solución interesante. ¿Existen diferencias en las estadísticas entre pares/períodos, cuál es la estabilidad en general de la variabilidad de la frecuencia de aparición de un patrón que da un resultado de predicción positivo?

En cuanto al zig-zag, también tengo una solución porcentual, pero también utilizo un historial más profundo para calcular un tramo de referencia del zig-zag, con el que comparo el cambio porcentual en otros.

 
Andrey Emelyanov:
En cuanto al análisis de indicadores con patrones, es muy interesante... Creo que hay menos ruido en los indicadores, pero hay que elegir los indicadores de manera que uno suprima el "ruido bajo" y el otro el "ruido alto", entonces se obtiene un multifiltro.
Hay muchos indicadores diferentes. He experimentado con los osciladores estándar (y su tipo de libre de interés), y he logrado obtener beneficios en todos ellos - todo depende de la configuración ... sólo una cuestión de si es aleatorio o regular.
 
Комбинатор:
¿Espera resultados con este modelo? Su capa interna actúa como un compresor intermedio, no como un clasificador.
Esa es la compresión que necesito... en un momento dado (en la barra actual) de las 64 entradas sólo 2 son distintas de cero... y la tarea de la red no es dividir por compra/venta, sino medir cuál es la probabilidad de un rebote en las entradas dadas. ¿O estoy razonando mal?
 
-Aleks-:

La matriz es una solución interesante. ¿Existe alguna diferencia en las estadísticas entre pares/períodos, cuál es la estabilidad en general de la variabilidad de la frecuencia de aparición del patrón que da un resultado de predicción positivo?

En cuanto al zig-zag, también tengo una solución porcentual, pero también utilizo un historial más profundo para calcular un tramo de referencia del zig-zag, con el que comparo el cambio porcentual en otros.

Como todo el mundo sabe, los patrones de A. Merrill no dan una respuesta exacta sobre si el patrón se desarrollará más (mantener la tendencia) o cambiará a otro patrón (rebote del precio). Por eso decidí buscar la respuesta utilizando dos marcos temporales: una hora y un minuto. Estoy recopilando estadísticas de recurrencia de pares y todavía no tengo un diccionario de formación universal. Sin embargo, estoy seguro de que esta conexión debe existir... De lo contrario, no habría patrones armoniosos: mariposas, murciélagos, etc.
 
Andrey Emelyanov:
Como todo el mundo sabe, los patrones de A. Merrill no dan una respuesta exacta sobre si el patrón se desarrollará más (mantener la tendencia) o cambiará a otro patrón (rebote del precio). Por eso decidí buscar la respuesta utilizando dos marcos temporales: una hora y un minuto. Recopilo estadísticas sobre la recurrencia de los pares y todavía no tengo un diccionario de formación universal. Sin embargo, estoy seguro de que esta conexión debe existir... De lo contrario, no habría modelos armoniosos: mariposas, murciélagos, etc.
Los modelos percibidos visualmente por un hombre como "mariposas, murciélagos, etc." nacen sólo en el cerebro humano y, como creo, es necesario considerar este factor, es necesario estudiar la psicología cognitiva sobre este tema para entender, lo que para el cerebro es esencial y lo que no es en la percepción del patrón, es decir, qué errores son aceptables y cuáles no. El cerebro suele completar lo que espera ver: su vocabulario de patrones es limitado, por lo que pone combinaciones similares de velas en una sola imagen, es decir, no utiliza el modelo matemático exacto para describir lo que ve.
 

Mi bebé sigue siendo tonto y aburrido, pero está llegando a algo... 8 indicadores de entrada, 1 de salida, 15 neuronas en la capa cubierta. 2000 vectores de entrada, 10000 épocas de entrenamiento.

En realidad es la tercera o cuarta, todas con los mismos resultados. Supongo que necesito más neuronas y un vector de entrada, pero se necesita mucho tiempo para entrenar.

Tengo una idea aproximada del patrón que debería recoger, he seleccionado indicadores de diferentes marcos temporales y las salidas parecen tener información significativa.