Aprendizaje automático en el trading: teoría, práctica, operaciones y más - página 7

 
Dr.Trader:

Gracias, lo he probado. Veo que has hecho mucho para seleccionar los predictores, porque las neuronas se entrenaron fácilmente con ellos, y almacenaron el resultado en el conjunto de datos de prueba también.

Los resultados siguientes se refieren a la formación en R1.F3

1) Hay un resultado curioso con Rattle. Los HH con configuración estándar mostraron errores de tren/validación/prueba del 30%/29%/33%. El error en R2.F3 es del 35%. Pero todo esto es sólo un caso de suerte en realidad, en otra configuración habría fácilmente sub- o sobre-entrenado, aquí sólo tuvo suerte.

2) Luego tomé un enfoque simple y crudo con aprendizaje no supervisado, 200 neuronas ocultas, la red fue entrenada hasta que dejó de mejorar. Errores de entrenamiento/validación/prueba/R2.F3 - 2%/30%/27%/45%. Evidentemente, la red está reentrenada.

3) Aprendizaje supervisado. Esto es diferente de los árboles, pero siempre hay que hacer esto con una neurona para no sobreentrenarla. La esencia de la misma es hacer una pausa en el entrenamiento de vez en cuando y comprobar los resultados del entrenamiento/validación/prueba. No conozco la regla de oro del cotejo de resultados, pero es bastante normal entrenar en el conjunto de datos de entrenamiento, luego buscar errores en los conjuntos de datos de validación y prueba, y dejar de entrenar cuando los errores en la validación/prueba dejan de caer. Esto ofrece una especie de garantía contra el sobreentrenamiento. El R2.F3 se considera no disponible durante todo este proceso, y la prueba sólo se realiza tras el final del entrenamiento. En este caso, los errores de tren/validación/prueba/R2.F3 son del 27%/30%/31%/37%. Aquí también hay sobreentrenamiento, pero no mucho. Podrías haber detenido el proceso de aprendizaje antes de que el error del tren fuera notablemente menor que los errores de validación/prueba, pero eso es una suposición... puede o no haber ayudado.

La variable objetivo "R1.F1" tiene tres valores, Rattle no puede hacer eso con las neuronas y tienes que escribir tu propio código en R, me salté este conjunto de datos.

"R1.F4" "R1.F5" "R1.F6" dieron más o menos los mismos resultados para los 4 errores en Rattle neuronka, creo que un enfoque adecuado con neuronka también dará más o menos los mismos resultados, no los he tratado más.

Tengo números similares para forest y ada.

Ahora, si volvemos a nuestros "espolones", ¿cómo descartar el ruido de una lista arbitraria de predictores? Tengo un algoritmo empírico que ha seleccionado mis 27 predictores de entre 170. También lo he utilizado para analizar los conjuntos de predictores de otras personas y también con éxito. Basándome en esta experiencia, sostengo que todos los métodos de R que utilizan variables de "importancia" en sus algoritmos no pueden limpiar de ruido el conjunto de predictores.

Hago un llamamiento a todos los lectores del hilo: estoy dispuesto a hacer el análisis correspondiente si los datos brutos se presentan como RData o un archivo Excel que no requiera procesamiento.

Aparte de eso.

Adjunto una serie de artículos que supuestamente resuelven el problema de limpiar de ruido el conjunto original de predictores, y con mucha mejor calidad. Desgraciadamente no tengo tiempo de probarlo en este momento. ¿Quizás alguien lo intente y publique el resultado?

Archivos adjuntos:
 
SanSanych Fomenko:

Se adjuntan varios artículos que supuestamente resuelven el problema de limpiar el conjunto original de predictores del ruido, y con mucha más calidad. Desgraciadamente no tengo tiempo de probarlo en este momento. ¿Quizás alguien lo pruebe y publique el resultado?

Gracias, he hojeado el documento, pero no he encontrado lo que necesito. Estoy tratando de entrenar mi modelo para forex, en algún lugar entre M15 y H4. No me basta con tomar los datos de la última barra, necesito tomarlos de decenas de barras a la vez y colocarlos uno tras otro en un array largo para las entradas del modelo. Por ejemplo (abrir_barra1, cerrar_barra1, hh_barra1, abrir_barra2, cerrar_barra2, hh_barra2, abrir_barra3, cerrar_barra3, hh_barra3,...). Si algún método de selección me dice que elimine la hora de la segunda barra, no me servirá, el método debería decirme que elimine por ejemplo todos los datos sobre la hora (índices 3,6,9...).

¿Lo he entendido bien, en su archivo ALL_cod.RData, puede utilizar Rat_DF1 para el entrenamiento también (especificando el objetivo necesario) y luego utilizar Rat_DF2 y Rat_DF3 para la comprobación? He adjuntado mi código en R para los interesados, implementa el entrenamiento de redes neuronales con control de errores. Para seleccionar otra variable de destino, basta con sustituir "Short_Long.75" por algo de "Short_Long.35", "Flet_Long", "Short_Flet", "Flet_In". Es más conveniente que sustituir diferentes conjuntos de datos.

Archivos adjuntos:
 
Dr.Trader:
Estoy tratando de entrenar mi modelo para forex, en algún lugar en el rango M15-H4. No me basta con tomar los datos de la última barra, necesito tomarlos de decenas de barras a la vez, y ponerlos uno tras otro en un array largo para las entradas del modelo. Por ejemplo (abrir_barra1, cerrar_barra1, hh_barra1, abrir_barra2, cerrar_barra2, hh_barra2, abrir_barra3, cerrar_barra3, hh_barra3,...). Si algún método de selección me dice que tengo que eliminar el tiempo de la segunda barra, no me servirá, el método debería decirme que puedo eliminar por ejemplo todos los datos de tiempo (índices 3,6,9...).

mmm Los datos de la hora pueden ser necesarios, ya que los mercados funcionan de forma diferente según la sesión.

Mira mi conjunto de características de Forex:

> names(sampleA)

  [1] "lag_diff_2"        "lag_diff_3"        "lag_diff_4"        "lag_diff_6"        "lag_diff_8"        "lag_diff_11"       "lag_diff_16"     

  [8] "lag_diff_23"       "lag_diff_32"       "lag_diff_45"       "lag_diff_64"       "lag_diff_91"       "lag_diff_128"      "lag_diff_181"    

 [15] "lag_diff_256"      "lag_diff_362"      "lag_diff_512"      "lag_diff_724"      "lag_mean_diff_2"   "lag_mean_diff_3"   "lag_mean_diff_4" 

 [22] "lag_mean_diff_6"   "lag_mean_diff_8"   "lag_mean_diff_11"  "lag_mean_diff_16"  "lag_mean_diff_23"  "lag_mean_diff_32"  "lag_mean_diff_45"

 [29] "lag_mean_diff_64"  "lag_mean_diff_91"  "lag_mean_diff_128" "lag_mean_diff_181" "lag_mean_diff_256" "lag_mean_diff_362" "lag_mean_diff_512"

[36] "lag_mean_diff_724" "lag_max_diff_2"    "lag_max_diff_3"    "lag_max_diff_4"    "lag_max_diff_6"    "lag_max_diff_8"    "lag_max_diff_11" 

 [43] "lag_max_diff_16"   "lag_max_diff_23"   "lag_max_diff_32"   "lag_max_diff_45"   "lag_max_diff_64"   "lag_max_diff_91"   "lag_max_diff_128"

 [50] "lag_max_diff_181"  "lag_max_diff_256"  "lag_max_diff_362"  "lag_max_diff_512"  "lag_max_diff_724"  "lag_min_diff_2"    "lag_min_diff_3"  

 [57] "lag_min_diff_4"    "lag_min_diff_6"    "lag_min_diff_8"    "lag_min_diff_11"   "lag_min_diff_16"   "lag_min_diff_23"   "lag_min_diff_32" 

 [64] "lag_min_diff_45"   "lag_min_diff_64"   "lag_min_diff_91"   "lag_min_diff_128"  "lag_min_diff_181"  "lag_min_diff_256"  "lag_min_diff_362"

 [71] "lag_min_diff_512"  "lag_min_diff_724"  "lag_sd_2"          "lag_sd_3"          "lag_sd_4"          "lag_sd_6"          "lag_sd_8"        

 [78] "lag_sd_11"         "lag_sd_16"         "lag_sd_23"         "lag_sd_32"         "lag_sd_45"         "lag_sd_64"         "lag_sd_91"       

 [85] "lag_sd_128"        "lag_sd_181"        "lag_sd_256"        "lag_sd_362"        "lag_sd_512"        "lag_sd_724"        "lag_range_2"     

 [92] "lag_range_3"       "lag_range_4"       "lag_range_6"       "lag_range_8"       "lag_range_11"      "lag_range_16"      "lag_range_23"    

 [99] "lag_range_32"      "lag_range_45"      "lag_range_64"      "lag_range_91"      "lag_range_128"     "lag_range_181"     "lag_range_256"   

[106] "lag_range_362"     "lag_range_512"     "lag_range_724"     "symbol"            "month"             "day"               "week_day"        

[113] "hour"              "minute"            "future_lag_2"      "future_lag_3"      "future_lag_4"      "future_lag_6"      "future_lag_8"    

[120] "future_lag_11"     "future_lag_16"     "future_lag_23"     "future_lag_32"     "future_lag_45"     "future_lag_64"     "future_lag_91"   

[127] "future_lag_128"    "future_lag_181"    "future_lag_256"    "future_lag_362"    "future_lag_512"    "future_lag_724"

Tomo tanto los datos de las medias móviles, como los máximos y mínimos, y los diferenciales de precios en la ventana. Y el tiempo, y los días e incluso los meses).

Mis algoritmos pueden dejar de forma realista 10 o incluso 5 de 114 predictores. Esto es normal. En estos datos hay una fuerte correlación entre los PREDICTORES y, por tanto, hay una fuerte redundancia.

 

Les voy a explicar brevemente mi método de selección de las características informativas. Se adjunta el código.

La cuestión tiene dos vertientes: cómo seleccionar los subconjuntos y cómo medir la relevancia de los predictores seleccionados para la variable de salida.

La primera pregunta. Lo resuelvo mediante la enumeración estocástica de combinaciones de predictores utilizando el método Simulated Annealing. Resultados similares a los de la genética y el descenso de gradiente no determinista. El lado positivo es que selecciona a partir de mínimos locales y funciona según el principio que está en la naturaleza. Puede funcionar con una superficie de error no lisa, pero aquí todo es condicional.

Para muchos problemas, los defensores del método lo consideran mejor que la genética, por ejemplo. Se implementa a través de un paquete en R como un estándar casi. El truco es que es para datos continuos, y tengo índices de predictores, así que hago un vector continuo de longitud en número total de predictores y cuando algún escalar rompe el umbral dado el índice del predictor se convierte en uno.

La segunda cuestión es aún más sutil. Función de aptitud.

Cómo medir que el predictor (y el conjunto de predictores) afecta al resultado. La dependencia puede ser no lineal. La regresión estándar puede obtener grandes retrasos en algunos problemas no lineales. No me refiero a la formación en caja negra ni a la utilización de un estimador de importancia incorporado. Me refiero a un método distinto.

Hay que entender que la dependencia puede ser muy compleja e implicar interacciones, redundancias, no linealidad de nuevo. Todo esto puede aplicarse tanto a los datos categóricos como a los numéricos.

He optado por los datos categóricos, ya que existen buenas herramientas de la Teoría de la Información para ello. En pocas palabras: hay una entrada y una salida. Si el estado de salida depende al menos un poco de la entrada (probabilísticamente), entonces son dependientes. Hay una cosa que se llama información mutua. Mide esto.

Ahora profundiza. VI mide algo sobre la distribución observada en una muestra de tamaño finito. Se trata, por supuesto, de una estimación puntual.

Así que tenemos que estimar los límites estadísticos de la información en el caso de un par de entrada-salida independiente. Esto se hace mediante una función de escritura propia que utiliza métodos numéricos.

Aún más profundo. Si tenemos dos o más predictores, ¿qué hacer con ellos?

En primer lugar, ellos mismos pueden estar relacionados y cuanto más relacionados estén, más redundancia habrá en su conjunto. Esta redundancia se mide por la llamada multiinformación. Pero la multinformación también es una estimación puntual sobre una muestra. Para ello, el cuantil de la distribución también se calcula numéricamente a través de otra función de escritura propia.

En segundo lugar, el número de niveles de las categorías predictoras puede ser tan grande (digamos, 2 ^ 15) que no se puede decir nada sobre la dependencia en estos niveles. Hay muy pocas observaciones por nivel.

Por último, cuando todo esto está hecho y reunido, podemos medir cualquier tipo de dependencia de un número arbitrario de predictores y resultados, en un tamaño de muestra arbitrario con una significación estadística predeterminada. Las funciones subyacentes están tomadas del paquete de Teoría de la Información.

Está todo en el archivo adjunto. Por supuesto, no es fácil entenderlo sin 100 gramos. También hay un código completo para crear reglas de negociación y su validación. Todo para su información y para profundizar en sus conocimientos.

Básicamente, el resultado es el de siempre:

[1] "1.69%"

> final_vector <- c((sao$par >= threshold), T)

> names(sampleA)[final_vector]

 [1] "lag_diff_23"      "lag_diff_45"      "lag_mean_diff_2"  "lag_mean_diff_8"  "lag_max_diff_11"  "lag_max_diff_181" "lag_min_diff_3"   "lag_min_diff_724"

 [9] "lag_sd_724"       "lag_range_32"     "symbol" "future_lag_181"  

Tras un día y medio de trabajo y la enumeración de decenas de miles de combinaciones de predictores, la función arroja un valor de la función de aptitud, que es una información mutua significativa penalizada por la redundancia en el conjunto de predictores. Y los propios predictores.

Todo esto, repito, es categórico y permite la construcción de reglas legibles para el ser humano. Permite interpretar el patrón encontrado.

Por ejemplo, arriba tengo un 1,7% de determinismo completo (que no está mal para el Forex) y un montón de inputs que juntos de forma significativa al nivel de confianza del 0,1 (pongo el experimento así) determinan el estado de salida (binario). Es decir, está claro que la información de los datos de Forex está presente. La cuestión está comprobada experimentalmente.

Después podemos evaluar en la validación la rentabilidad y codificar el sistema de comercio.

Alexey

Archivos adjuntos:
 
Dr.Trader:


¿He entendido bien que en su archivo ALL_cod.RData también puede utilizar Rat_DF1 para el entrenamiento (especificando el objetivo deseado) y luego utilizar Rat_DF2 y Rat_DF3 para la comprobación? He adjuntado mi código en R para los interesados, implementa el entrenamiento de redes neuronales con control de errores. Para seleccionar otra variable de destino, basta con sustituir "Short_Long.75" por algo de "Short_Long.35", "Flet_Long", "Short_Flet", "Flet_In". Esto es más conveniente que sustituir diferentes conjuntos de datos.

Sí. Exactamente para la comodidad en el traqueteo.

Un matiz más.

Todas las variables objetivo se derivan de dos ZZ: ZZ(35) y ZZ(25). Y aquí hay un matiz muy desagradable que resuena con el suyo.

La variable objetivo es una secuencia de 0 y 1, que corresponde al brazo ZZ. Pero SIEMPRE predecimos un solo elemento del brazo ZZ, no el brazo en sí. Por tanto, es incorrecto decir que estamos prediciendo tendencias. Es correcto decir que estamos prediciendo un elemento de una tendencia. Y si se suman todos los elementos de tendencia previstos, la tendencia probablemente no funcionará.

 

Gracias por feature_selector_modeller.zip, lo investigaré.

SanSanych Fomenko:

Me dirijo a todos los lectores de la rama: estoy dispuesto a hacer el análisis correspondiente, si los datos iniciales se presentarán en forma de archivo RData o Excel, que no requiere procesamiento.

He adjuntado el archivo, es un conjunto de datos de forex. Dentro de RData con dos conjuntos de datos, para el entrenamiento y para la validación. Físicamente, los datos de los dos conjuntos de datos van uno detrás del otro, están divididos en dos archivos sólo por la conveniencia de probar el modelo. El modelo en este conjunto de datos se puede entrenar, yo seleccioné manualmente los predictores y entrené la neurona, al final el error mínimo en el conjunto de datos de validación fue del 46%, que no es realmente rentable. Se puede pensar en un beneficio real si el error cae por debajo del 40%. Trata de tamizar los predictores de este archivo, por favor.

SanSanych Fomenko:

La variable objetivo es una secuencia de 0 y 1, que corresponde a la palanca ZZ. Pero SIEMPRE predecimos un elemento individual del brazo ZZ, no el brazo en sí. Por tanto, es incorrecto decir que estamos prediciendo tendencias. Es correcto decir que estamos prediciendo un elemento de una tendencia. Y si se suman todos los elementos de tendencia previstos, probablemente ni siquiera se obtendrá una tendencia.

He probado diferentes variables de destino. Por un lado, se puede predecir el precio con una barra de antelación y entonces la variable objetivo será 1 o 0 dependiendo de si el precio de la siguiente barra es alcista o bajista. Nunca obtuve ningún resultado en marcos temporales pequeños, el precio de cierre parece ser un número bastante aleatorio en ellos. Pero en H1 y superior ya hay algún resultado positivo.

Otra variante es el zigzag u otros indicadores de tendencia. Conseguí algunos resultados positivos con él pero con la condición de que el resultado de las neuronas pase por el filtro. Por ejemplo, tomar la media de los resultados de los últimos compases o utilizar los resultados sólo por encima de un determinado valor umbral. En mi opinión, no vale la pena aplicar todo eso, son más conjeturas que cálculos precisos. El problema es que el modelo debe dar sólo señales de compra para las próximas 10-20 barras, mientras que a veces da señales de venta entre ellas. En tal caso, se invierte la operación, se paga la comisión y el diferencial, y así varias veces por tendencia. Por lo tanto, debemos obtener una alta precisión o suavizar los resultados para evitar tales inversiones en una sola barra. Es decir, como usted ha dicho, sólo se predice un elemento de una tendencia; la tendencia en sí no puede estar compuesta por esos elementos.

Archivos adjuntos:
set56.RData.zip  525 kb
 
Dr.Trader:


He probado diferentes variables de destino. Por un lado, puede predecir el precio con una barra de antelación y entonces la variable objetivo será 1 o 0 dependiendo de si el precio de la siguiente barra ha subido o bajado. Nunca obtuve ningún resultado en marcos temporales pequeños, parece que el precio de cierre es un número bastante aleatorio en ellos. Pero en H1 y superior ya hay algún resultado positivo.


Mis resultados son sistemáticamente los contrarios. Puedo predecir fácilmente el movimiento de los precios con unos minutos de antelación (hasta una hora) con un 55% de precisión (Ask to Ask). El mejor resultado para 23 minutos. Es una clasificación binaria sobre muestras de validación.

Y a medida que aumenta el horizonte de previsión, la precisión desciende lentamente hasta el 51% a 12 horas vista. Y esta dependencia está presente en toda la historia. Pero la precisión tiene que ser aún mayor para llegar al lado positivo (para superar la distancia Ask - Bid).

Lo discutiremos más adelante.

 
Dr.Trader:

Gracias por el feature_selector_modeller.zip, lo investigaré.

He adjuntado el archivo, es un conjunto de datos de Forex. Dentro de RData con dos conjuntos de datos, para el entrenamiento y para la validación. Físicamente los datos de los dos conjuntos de datos se suceden, se dividen en dos archivos sólo por la conveniencia de probar el modelo. El modelo en este conjunto de datos se puede entrenar, yo seleccioné manualmente los predictores y entrené la neurona, al final el error mínimo en el conjunto de datos de validación fue del 46%, que no es realmente rentable. Se puede pensar en un beneficio real si el error cae por debajo del 40%. Trata de tamizar los predictores de este archivo, por favor.


No he encontrado ningún predictor, todos son ruido. Sus predictores no tienen poder predictivo para su variable objetivo. Algunas pistas 54,55,56. Podrías sacar algo de ellos... Por lo demás, en lo que a mí respecta, todo puede ser desechado.
 
Ya veo, gracias, buscaré otras aportaciones.
 
Dr.Trader:
Ya veo, gracias, buscaré otros datos en bruto.

Aguanta. También analizaré tus datos para ver las dependencias.

Una pregunta antes de empezar. ¿Incluye sus datos todas las barras de una fila, o hubo un adelgazamiento de las barras antes de hacer las muestras?

Razón de la queja: